msvisual.com Forum Index
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Preventing all thread's windows becoming foreground when one

 
Post new topic   Reply to topic    msvisual.com Forum Index -> VB WinAPI
Author Message
Johannes Franke



Joined: 18 Feb 2008
Posts: 2

PostPosted: Mon Feb 18, 2008 8:38 pm    Post subject: Preventing all thread's windows becoming foreground when one Reply with quote

Hi all,

seems like I am trying to fight a "feature" here. Well, maybe there is some
help.
I am developing a multi-window Office add-on. It's not MDI, and the windows
are not all the same. As I don't want to handicap users working with Office
by modal dialogs, I have decided to make most of the dialogs modeless. Thus,
it is possible to open about 10 different windows simultaneously without
blocking the Office program.
The issue is that on activating any of the dialogs (by clicking the mouse in
it or activating the appropriate window button in the task bar), all of the
other open windows of my app are also put to the foreground even if the user
wanted to gain access only of the one form he/she clicked.
I suspect that this is an intended behaviour of VB6, but for me it's rather
inconvenient and I'd like to know about ways to get around it. I cannot put
each window in a different thread (it's VB6), and even if it were possible
that way, it still demands too much time to develop and may have some
negative impact on the application's overall stability.

Steps for reproduction:

- create a new standard VB6 EXE project
- add a new module to the project so now you have an unnamed form and an
unnamed module
- in the project properties, set startup mode to "Sub Main()"
- create a sub Main() in the module, with the following source code:

Sub Main()

Dim oFrm As Form1
Dim n As Long

For n = 1 To 10
Set oFrm = New Form1
Call oFrm.Show
Set oFrm = Nothing
Next

End Sub

Running the project will result in a cascade of 10 windows in the top-left
corner of the screen. Drag any of them to a random screen position, then put
some different window in the foreground in the top-left corner (e.g. an
Explorer) so it hides the other nine windows at least partially.
Clicking on the one you dragged away will show not only the one on which you
clicked, but also the nine other windows from behind the Explorer will
reappear in front of it unintendedly. You can repeat this with any of the 10
windows. Activating any of them will always make all of the windows topmost.
Is there some way to make sure that the nine hidden windows stay in the
background in this situation? I'd like to do this the cleanest way possible
to make sure it runs in any environment, does not produce flicker or other
inconveniences.

Thank you a lot for your help!

Regards,
Joe

Archived from group: microsoft>public>vb>winapi
Back to top
View user's profile Send private message
Vinchenzo_vinç



Joined: 04 Oct 2007
Posts: 33

PostPosted: Mon Feb 18, 2008 9:50 pm    Post subject: Re: Preventing all thread's windows becoming foreground when Reply with quote

"Johannes Franke" escribió en el mensaje @TK2MSFTNGP02.phx.gbl...
> Hi all,
>
> ...
> The issue is that on activating any of the dialogs (by clicking the mouse in
> it or activating the appropriate window button in the task bar), all of the
> other open windows of my app are also put to the foreground even if the user
> wanted to gain access only of the one form he/she clicked.
> I suspect that this is an intended behaviour of VB6,

Hi, this is the default realationship of all Forms created by your app, there is a 0x0 pixels window called 'Thunder[RTversion]Main", it is their *owner*, if you minimize the owner, all owned are minimized, if you destroy de owner, all owned are destroyed, ...and so on.
For your task, you can remove (set to Null) the owner of any Form that you want to "detach/unlink/free", changing the GWL_HWNDPARENT bit with the SetWindowLong function.

For example, following your sample code:

'****************
Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" ( _
ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Const GWL_HWNDPARENT As Long = -8

Sub Main()

Dim oFrm As Form1
Dim n As Long

For n = 1 To 10
Set oFrm = New Form1
Call oFrm.Show
SetWindowLong oFrm.hWnd, GWL_HWNDPARENT, 0& '<<<<
Set oFrm = Nothing
Next

End Sub
'****************


--
Regards
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Preceding answers in Google:
http://groups.google.com/group/microsoft.public.vb.winapi
( i ) Temperance in the forum:
http://www.microsoft.com/communities/conduct/default.mspx
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Back to top
View user's profile Send private message
Johannes Franke



Joined: 18 Feb 2008
Posts: 2

PostPosted: Mon Feb 18, 2008 10:07 pm    Post subject: Re: Preventing all thread's windows becoming foreground when Reply with quote

Dear Vinchenzo,

great, that did it! Thank you very much for your explanations.

Greetings from Germany
Johannes


"Vinchenzo vinç" schrieb im Newsbeitrag
news:%23pMZQYkcIHA.4696@TK2MSFTNGP05.phx.gbl...

"Johannes Franke" escribió en el mensaje @TK2MSFTNGP02.phx.gbl...
> Hi all,
>
> ...
> The issue is that on activating any of the dialogs (by clicking the mouse
> in
> it or activating the appropriate window button in the task bar), all of
> the
> other open windows of my app are also put to the foreground even if the
> user
> wanted to gain access only of the one form he/she clicked.
> I suspect that this is an intended behaviour of VB6,

Hi, this is the default realationship of all Forms created by your app,
there is a 0x0 pixels window called 'Thunder[RTversion]Main", it is their
*owner*, if you minimize the owner, all owned are minimized, if you destroy
de owner, all owned are destroyed, ...and so on.
For your task, you can remove (set to Null) the owner of any Form that
you want to "detach/unlink/free", changing the GWL_HWNDPARENT bit with the
SetWindowLong function.

For example, following your sample code:

'****************
Private Declare Function SetWindowLong Lib "user32.dll" Alias
"SetWindowLongA" ( _
ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As
Long
Private Const GWL_HWNDPARENT As Long = -8

Sub Main()

Dim oFrm As Form1
Dim n As Long

For n = 1 To 10
Set oFrm = New Form1
Call oFrm.Show
SetWindowLong oFrm.hWnd, GWL_HWNDPARENT, 0& '<<<<
Set oFrm = Nothing
Next

End Sub
'****************


--
Regards
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Preceding answers in Google:
http://groups.google.com/group/microsoft.public.vb.winapi
( i ) Temperance in the forum:
http://www.microsoft.com/communities/conduct/default.mspx
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Back to top
View user's profile Send private message
Karl E. Peterson



Joined: 04 Oct 2007
Posts: 4836

PostPosted: Tue Feb 19, 2008 6:06 pm    Post subject: Re: Preventing all thread's windows becoming foreground when Reply with quote

Ed wrote:
> On Mon, 18 Feb 2008 16:50:50 +0100, Vinchenzo vinç
> wrote:
>
>>'****************
>>Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" ( _
>> ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
>>Private Const GWL_HWNDPARENT As Long = -8
>>
>>Sub Main()
>>
>> Dim oFrm As Form1
>> Dim n As Long
>>
>> For n = 1 To 10
>> Set oFrm = New Form1
>> Call oFrm.Show
>> SetWindowLong oFrm.hWnd, GWL_HWNDPARENT, 0& '<<<<
>> Set oFrm = Nothing
>> Next
>>
>>End Sub
>>'****************
>
> Hi,
>
> Nice solution, but one problem, my form is set to ShowInTaskbar=False
> and now when a form gets focus it shows up in the Taskbar.
>
> Anyway to keep the forms from showing up in the Taskbar?

Take a look at http://vb.mvps.org/samples/FormBdr for one method to toggle the
ShowInTaskbar property at runtime.
--
..NET: It's About Trust!
http://vfred.mvps.org
Back to top
View user's profile Send private message
Karl E. Peterson



Joined: 04 Oct 2007
Posts: 4836

PostPosted: Wed Feb 20, 2008 4:39 pm    Post subject: Re: Preventing all thread's windows becoming foreground when Reply with quote

Ed wrote:
> On Tue, 19 Feb 2008 13:06:20 -0800, "Karl E. Peterson"
> wrote:
>
>>Take a look at http://vb.mvps.org/samples/FormBdr for one method to toggle the
>>ShowInTaskbar property at runtime.
>
> Doesn't seem to work with SetWindowLong oFrm.hWnd, GWL_HWNDPARENT, 0&

Hmmmm, yeah, confirmed.

Is there another common application that exhibits the behavior you're attempting to
implement? If so, we might be able to glean a few hints from that. If not, well,
perhaps there's a reason.
--
..NET: It's About Trust!
http://vfred.mvps.org
Back to top
View user's profile Send private message
Vinchenzo_vinç



Joined: 04 Oct 2007
Posts: 33

PostPosted: Thu Feb 21, 2008 5:15 am    Post subject: Re: Preventing all thread's windows becoming foreground when Reply with quote

"Ed" escribió en el mensaje @4ax.com...
> On Mon, 18 Feb 2008 16:50:50 +0100, Vinchenzo vinç
> wrote:
>
> Hi,
>
> Nice solution, but one problem, my form is set to ShowInTaskbar=False
> and now when a form gets focus it shows up in the Taskbar.
>
> Anyway to keep the forms from showing up in the Taskbar?
>

Hi Ed, of course there is a way, ...mimicking more or less the VB's way.

Use the CreateWindowEx function to create a new 0x0 pixels "Thunder[RTversion]Main", window with the styles WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_OVERLAPPED, and the extended styles WS_EX_LEFT|WS_EX_LTREADING|WS_EX_RIGHTSCROLLBAR|WS_EX_TOOLWINDOW.
Set a new owner to all Forms that you want independent to each other, and those with ShowInTaskbar=False will not show its icon in the taskbar:

'****************
···

Set oFrm = New Form1
Call oFrm.Show
SetWindowLong oFrm.hwnd, _
GWL_HWNDPARENT, _
CreateWindowEx( _
&H80, "ThunderMain", _
vbNullString, &H94000000, _
0&, 0&, 0&, 0&, 0&, 0&, _
GetWindowLong(oFrm.hwnd, GWL_HINSTANCE), _
0&)

···
'****************

Set the appropiate window classname, "ThunderMain" if you test it in the IDE, or compiled for instance in VB6 "ThunderRT6Main".


--
Regards
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Preceding answers in Google:
http://groups.google.com/group/microsoft.public.vb.winapi
( i ) Temperance in the forum:
http://www.microsoft.com/communities/conduct/default.mspx
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    msvisual.com Forum Index -> VB WinAPI All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group