Home |
Search |
Today's Posts |
#1
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Hi Folks --
Is there any sort of agreed upon "best practice" for obtaining the hWnd of VBA UserForms? Something that'll pretty much work wherever VBA may be found? I seem to generally use some variation of this: Option Explicit Private Declare Function GetForegroundWindow Lib "user32" () As Long Private hWnd As Long Private Sub UserForm_Activate() hWnd = GetForegroundWindow() Debug.Print Hex$(hWnd) End Sub But I'm pretty much only working in either Word or Excel, and version 2003 at that. Any reason to think that wouldn't work in PowerPoint, Access, 2007, 2000, elsewhere, ....? Is there a better (more universal) way? Thanks... Karl -- ..NET: It's About Trust! http://vfred.mvps.org |
#2
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Karl, I have limited experience with such matters, but I'll share my
observations and conclusions: Some months ago I was attempting to manage position of the Assistant Balloon in Access (2003). After many hours of digging around API information I came to the sad conclusion that with respect to Access, at any rate, I was pursuing a hopeless cause as to the best of my ability to discover, all internal Access position information was relative to the user area of the Access window, *not* the Windows display area (as is hWnd). I believe that it would be possible to develop routines that would be able to "travel between the two worlds" but for my purposes it was not worth the effort. I also understand that VBA UserForms and Access Forms are completely different, and properties and methods effectively have no correlation from one to the other. I have also observed that the Excel and Access Application Objects handle windows and screens very differently. Not much to offer, but perhaps of some use to you. -- Clif "Karl E. Peterson" wrote in message ... Hi Folks -- Is there any sort of agreed upon "best practice" for obtaining the hWnd of VBA UserForms? Something that'll pretty much work wherever VBA may be found? I seem to generally use some variation of this: Option Explicit Private Declare Function GetForegroundWindow Lib "user32" () As Long Private hWnd As Long Private Sub UserForm_Activate() hWnd = GetForegroundWindow() Debug.Print Hex$(hWnd) End Sub But I'm pretty much only working in either Word or Excel, and version 2003 at that. Any reason to think that wouldn't work in PowerPoint, Access, 2007, 2000, elsewhere, ...? Is there a better (more universal) way? Thanks... Karl -- .NET: It's About Trust! http://vfred.mvps.org -- Clif |
#3
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Hi Karl, what are you doing over here... slumming? <g I only do Excel (now), so I can't speak for the other Office products, but you can find an Excel UserForm's hWnd using the FindWindow API. Here is a working line from the UserForm's Initialize event from one of my previous postings ... hWnd = FindWindow("ThunderDFrame", Me.Caption) I have no idea whether ThunderDFrame is usable elsewhere. -- Rick (MVP - Excel) "Karl E. Peterson" wrote in message ... Hi Folks -- Is there any sort of agreed upon "best practice" for obtaining the hWnd of VBA UserForms? Something that'll pretty much work wherever VBA may be found? I seem to generally use some variation of this: Option Explicit Private Declare Function GetForegroundWindow Lib "user32" () As Long Private hWnd As Long Private Sub UserForm_Activate() hWnd = GetForegroundWindow() Debug.Print Hex$(hWnd) End Sub But I'm pretty much only working in either Word or Excel, and version 2003 at that. Any reason to think that wouldn't work in PowerPoint, Access, 2007, 2000, elsewhere, ...? Is there a better (more universal) way? Thanks... Karl -- .NET: It's About Trust! http://vfred.mvps.org |
#4
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Hi Clif --
Well, okay, ya made me look. <g I just tried the code I suggested, in Access 2003, and it worked fine. (It appears Rick's FindWindow call would work, as well, given the classname for the Access UserForm is the same as Word or Excel.) Note, I'm not looking at the Access forms, but the VBA UserForms, here. Thanks... Karl Clif McIrvin wrote: Karl, I have limited experience with such matters, but I'll share my observations and conclusions: Some months ago I was attempting to manage position of the Assistant Balloon in Access (2003). After many hours of digging around API information I came to the sad conclusion that with respect to Access, at any rate, I was pursuing a hopeless cause as to the best of my ability to discover, all internal Access position information was relative to the user area of the Access window, *not* the Windows display area (as is hWnd). I believe that it would be possible to develop routines that would be able to "travel between the two worlds" but for my purposes it was not worth the effort. I also understand that VBA UserForms and Access Forms are completely different, and properties and methods effectively have no correlation from one to the other. I have also observed that the Excel and Access Application Objects handle windows and screens very differently. Not much to offer, but perhaps of some use to you. -- Clif "Karl E. Peterson" wrote in message ... Hi Folks -- Is there any sort of agreed upon "best practice" for obtaining the hWnd of VBA UserForms? Something that'll pretty much work wherever VBA may be found? I seem to generally use some variation of this: Option Explicit Private Declare Function GetForegroundWindow Lib "user32" () As Long Private hWnd As Long Private Sub UserForm_Activate() hWnd = GetForegroundWindow() Debug.Print Hex$(hWnd) End Sub But I'm pretty much only working in either Word or Excel, and version 2003 at that. Any reason to think that wouldn't work in PowerPoint, Access, 2007, 2000, elsewhere, ...? Is there a better (more universal) way? Thanks... Karl -- .NET: It's About Trust! http://vfred.mvps.org -- ..NET: It's About Trust! http://vfred.mvps.org |
#5
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Hi Rick --
Hi Karl, what are you doing over here... slumming? <g I actually lurk a lot, but don't have much reason to chime in because most of the questions are about the object model(s). And, more importantly, VBA is the only Road Forward for ClassicVB at this point. Gotta keep the brand alive! I only do Excel (now), so I can't speak for the other Office products, but you can find an Excel UserForm's hWnd using the FindWindow API. Here is a working line from the UserForm's Initialize event from one of my previous postings ... hWnd = FindWindow("ThunderDFrame", Me.Caption) I have no idea whether ThunderDFrame is usable elsewhere. That seems to be a pretty common classname. I see it throughout Office 2003, but was afraid it might change from version to version. (Anyone know how universal it is?) Your method has the advantage of being callable on demand, while the method I suggested is only good when the form first fires up. So I would think FindWindow might indeed be a better way to go, *if* the classname is stable. Thanks... Karl -- ..NET: It's About Trust! http://vfred.mvps.org |
#6
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Hi Karl,
I'm not an API expert, but to get the handle for the word application window GetActiveWindow Lib "user32" () As Long works pretty fine : -) Kind Regards, Manfred |
#7
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Well hello again Karl!
As Rick says it's - hWnd = FindWindow("ThunderDFrame", Me.Caption) That's good for Excel 2000+ and AFAIK all Office 2000 or later with VBA6. If you want to cater for anyone still using Office97 (most don't but I do) - If Val(Application.Version) = 9 Then sClassName = "ThunderDFrame" Else sClassName = "ThunderXFrame" End If instead of checking the app version you could do #If VBA6 ... #Else If ... #End IF but will need a bit more for 2010/64bit If there's any possibility a form with a similar caption could be showing elsewhere, even in another instance, best to temporarily change the caption to something unique. Regards, Peter T "Karl E. Peterson" wrote in message ... Hi Folks -- Is there any sort of agreed upon "best practice" for obtaining the hWnd of VBA UserForms? Something that'll pretty much work wherever VBA may be found? I seem to generally use some variation of this: Option Explicit Private Declare Function GetForegroundWindow Lib "user32" () As Long Private hWnd As Long Private Sub UserForm_Activate() hWnd = GetForegroundWindow() Debug.Print Hex$(hWnd) End Sub But I'm pretty much only working in either Word or Excel, and version 2003 at that. Any reason to think that wouldn't work in PowerPoint, Access, 2007, 2000, elsewhere, ...? Is there a better (more universal) way? Thanks... Karl -- .NET: It's About Trust! http://vfred.mvps.org |
#8
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Manfred F wrote:
I'm not an API expert, but to get the handle for the word application window GetActiveWindow Lib "user32" () As Long works pretty fine : -) You have very good company on that advice! http://blogs.msdn.com/oldnewthing/ar...6/8969399.aspx I shall consider myself appropriately admonished for habitual overreach, here. Thanks... :-) -- ..NET: It's About Trust! http://vfred.mvps.org |
#9
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Peter T wrote:
Well hello again Karl! As Rick says it's - hWnd = FindWindow("ThunderDFrame", Me.Caption) That's good for Excel 2000+ and AFAIK all Office 2000 or later with VBA6. Good to know! If you want to cater for anyone still using Office97 (most don't but I do) - Ewww, no. Not anymore, thanks. :-) If Val(Application.Version) = 9 Then sClassName = "ThunderDFrame" Else sClassName = "ThunderXFrame" End If Still, a good nugget to have. instead of checking the app version you could do #If VBA6 ... #Else If ... #End IF but will need a bit more for 2010/64bit As I recall, and this is a very dim memory, that constant is predefined in VBA, right? So I can use it in normal VB6 code, and it'll only come into play if the code is sucked into VBA? I keep forgetting that. It's an incredibly useful tidbit! If there's any possibility a form with a similar caption could be showing elsewhere, even in another instance, best to temporarily change the caption to something unique. Yep. That's one of the reasons I tended against the FindWindow approach, as well. But the GetActiveWindow approach is going to work pretty well, I think. -- ..NET: It's About Trust! http://vfred.mvps.org |
#10
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Hi Karl,
"Karl E. Peterson" wrote: You have very good company on that advice! http://blogs.msdn.com/oldnewthing/ar...6/8969399.aspx Thank You very much for this clarifying info. I've only got a limited understanding of API functions, but - by occasion - I was right then: I use the GetActiveWindow to get "my" active word window and use GetForegroundWindow to check whether word is in the foreground before I display a userform or a messagebox. Eventually, I set "my" window to the foreground before.. Regards, Manfred |
#11
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
"Karl E. Peterson" wrote in message instead of checking the app version you could do #If VBA6 ... #Else If ... #End IF but will need a bit more for 2010/64bit As I recall, and this is a very dim memory, that constant is predefined in VBA, right? It exists in Office 2000+ VBA. It's main usage was to allow new VBA6 code to compile in Office97 #If VBA6 then use new method stuff which would bomb in Excel97 #Else work around with old ways #End If So I can use it in normal VB6 code, and it'll only come into play if the code is sucked into VBA? Yes in the sense it doesn't exist in VB6, even with all the references to VBA and object model. #If VBA6 then ' this code module is being used in VBA #Else ' this code module is in VB6 (but conceivably in say xl97) #End if IIRC this came up when discussing your SendKeys replacement. If there's any possibility a form with a similar caption could be showing elsewhere, even in another instance, best to temporarily change the caption to something unique. Yep. That's one of the reasons I tended against the FindWindow approach, as well. But the GetActiveWindow approach is going to work pretty well, I think. Typically want to get the form's hWnd in the Initialize event, I assume the only time GetActiveWindow could be reliably used is in the form's Activate event? I'm curious though, what are the other reasons you tend against FindWindow, even with a unique caption. Regards, Peter T |
#12
Posted to microsoft.public.excel.programming,microsoft.public.office.developer.vba,microsoft.public.word.vba.general
|
|||
|
|||
Best Practice for Obtaining hWnd
Peter T wrote: "Karl E. Peterson" wrote in message So I can use it in normal VB6 code, and it'll only come into play if the code is sucked into VBA? Yes in the sense it doesn't exist in VB6, even with all the references to VBA and object model. #If VBA6 then ' this code module is being used in VBA #Else ' this code module is in VB6 (but conceivably in say xl97) #End if IIRC this came up when discussing your SendKeys replacement. Ahhh, right. I must burn this into my memory, because it's an incredibly useful way to distinguish the slight differences in approach required between the two. If there's any possibility a form with a similar caption could be showing elsewhere, even in another instance, best to temporarily change the caption to something unique. Yep. That's one of the reasons I tended against the FindWindow approach, as well. But the GetActiveWindow approach is going to work pretty well, I think. Typically want to get the form's hWnd in the Initialize event, I assume the only time GetActiveWindow could be reliably used is in the form's Activate event? No, it oughta work anytime the user is interacting. But, hmmm, yeah if the form were non-modal, it could conceivably return one of the main application windows as well. Probably best to stick with caching the value at first activation. I'm curious though, what are the other reasons you tend against FindWindow, even with a unique caption. Assuming the unique caption is one strike, for sure. But you also have no "future-proofing" if they happen to change the classname. Those would be the bigger drawbacks. But neither is so large as to be deal killers. -- ..NET: It's About Trust! http://vfred.mvps.org |
Reply |
Thread Tools | Search this Thread |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Forum | |||
Excel 2007 statusbar hWnd | Excel Programming | |||
HWND of Listbox in UserForm in Excel macro | Excel Programming | |||
Getting hWnd for API call or Color choosing dialog | Excel Programming | |||
hWnd of UserForm | Excel Programming | |||
how to get hwnd from application object? | Excel Programming |