| Home | Forums | Reviews | Articles | Register |
![]() |
| Thread Tools | Rate Thread |
|
|
|
| |
|
RB Smissaert
Guest
Posts: n/a
|
Try this:
Instead of calling AddressOf directly call it via a function like this: Function FARPROC(ByVal pfn As Long) As Long FARPROC = pfn End Function RBS <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > OK, so I'm pretty new to API's so forgive me if this is an idiot > question :-) > > I'm putting together a class that uses API calls to user32 to > enumerate and list all running applications by their Title text. One > of the functions uses "AddressOf AnotherFunctionName" to accomplish > this. The code works fantastic in a module. However, when trying to > migrate this to a reusable class, the code crashes on that line with > an error of: > > "Invalid use of AddressOf operator" > > Looking in Help it says: > "You tried to use AddressOf with the name of a class method. > Only the names of Visual Basic procedures in a .bas module can be > modified with AddressOf. You can't specify a class method." > > Well, shucks, that just popped my bubble of wanting to make this code > really efficient by keeping it in a class amongst some other utility > functions I've written. Seems I can only use it in a module instead. > > My question is this: Is there a way to work around this in a class? > Here's my working module code that simply returns a Long greater than > zero if an app with all or part of the passed title is found to be > running: > > ================================== > Option Explicit > > Private Declare Function EnumWindows Lib "user32" (ByVal lEnumFunc As > Long, ByVal wParam As Long) As Long > > Private Declare Function GetWindowText Lib "user32" Alias > "GetWindowTextA" _ > (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As > Long > > Private Type AppWindow > sTitle As String > lHandle As Long > End Type > > Public Function FindWindowByTitle(ByVal TheWindowTitle As String) As > Long > 'We'll pass a custom structure in as the parameter to store our > result... > Dim tParms As AppWindow > tParms.sTitle = TheWindowTitle > > Call EnumWindows(AddressOf GetWindowTitles, VarPtr(tParms)) > > FindWindowByTitle = tParms.lHandle > End Function > > Private Function GetWindowTitles(ByVal TheHandle As Long, TheParms As > AppWindow) As Long > Dim sTitleText As String > > 'set a generic 260 length empty string to catch the window text > sTitleText = Space(260) > 'get the text > Call GetWindowText(TheHandle, sTitleText, 260) > 'remove nulls from the text > sTitleText = TrimNull(sTitleText) > > 'check to see if all or part of the search string is found > 'in the window text > If sTitleText Like TheParms.sTitle Then > 'if a match is found, then set the handle number > TheParms.lHandle = TheHandle > 'and then exit the function > GetWindowTitles = 0 > End If > > 'reset to 1 to keep the recursive loop going if not match found > GetWindowTitles = 1 > End Function > > Private Function TrimNull(ByVal TheText As String) > 'check to see if string has null characters on the end > If Not InStr(TheText, Chr$(0)) = 0 Then > 'if so, then remove the null characters from the end > TheText = Left$(TheText, InStr(TheText, Chr$(0)) - 1) > End If > TrimNull = TheText > End Function > ======================================= > > Of course the usage of this would be to pass a string to the only > public function FindWindowByTitle. > > Thanks for any light that can be shed on this. > > Cory > |
|
||
|
||||
|
RB Smissaert
Guest
Posts: n/a
|
I forgot to give an example:
With CC 'base flag .flags = CC_ANYCOLOR .flags = .flags Or CC_FULLOPEN .flags = .flags Or CC_RGBINIT .rgbResult = lStartColour .flags = .flags Or CC_ENABLEHOOK .lpfnHook = FARPROC(AddressOf ChooseColorProc) 'size of structure .lStructSize = Len(CC) 'assign the custom colour selections .lpCustColors = VarPtr(dwCustClrs(0)) End With RBS "RB Smissaert" <(E-Mail Removed)> wrote in message news:%(E-Mail Removed)... > Try this: > > Instead of calling AddressOf directly call it via a function like this: > > Function FARPROC(ByVal pfn As Long) As Long > > FARPROC = pfn > > End Function > > > RBS > > <(E-Mail Removed)> wrote in message > news:(E-Mail Removed)... >> OK, so I'm pretty new to API's so forgive me if this is an idiot >> question :-) >> >> I'm putting together a class that uses API calls to user32 to >> enumerate and list all running applications by their Title text. One >> of the functions uses "AddressOf AnotherFunctionName" to accomplish >> this. The code works fantastic in a module. However, when trying to >> migrate this to a reusable class, the code crashes on that line with >> an error of: >> >> "Invalid use of AddressOf operator" >> >> Looking in Help it says: >> "You tried to use AddressOf with the name of a class method. >> Only the names of Visual Basic procedures in a .bas module can be >> modified with AddressOf. You can't specify a class method." >> >> Well, shucks, that just popped my bubble of wanting to make this code >> really efficient by keeping it in a class amongst some other utility >> functions I've written. Seems I can only use it in a module instead. >> >> My question is this: Is there a way to work around this in a class? >> Here's my working module code that simply returns a Long greater than >> zero if an app with all or part of the passed title is found to be >> running: >> >> ================================== >> Option Explicit >> >> Private Declare Function EnumWindows Lib "user32" (ByVal lEnumFunc As >> Long, ByVal wParam As Long) As Long >> >> Private Declare Function GetWindowText Lib "user32" Alias >> "GetWindowTextA" _ >> (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As >> Long >> >> Private Type AppWindow >> sTitle As String >> lHandle As Long >> End Type >> >> Public Function FindWindowByTitle(ByVal TheWindowTitle As String) As >> Long >> 'We'll pass a custom structure in as the parameter to store our >> result... >> Dim tParms As AppWindow >> tParms.sTitle = TheWindowTitle >> >> Call EnumWindows(AddressOf GetWindowTitles, VarPtr(tParms)) >> >> FindWindowByTitle = tParms.lHandle >> End Function >> >> Private Function GetWindowTitles(ByVal TheHandle As Long, TheParms As >> AppWindow) As Long >> Dim sTitleText As String >> >> 'set a generic 260 length empty string to catch the window text >> sTitleText = Space(260) >> 'get the text >> Call GetWindowText(TheHandle, sTitleText, 260) >> 'remove nulls from the text >> sTitleText = TrimNull(sTitleText) >> >> 'check to see if all or part of the search string is found >> 'in the window text >> If sTitleText Like TheParms.sTitle Then >> 'if a match is found, then set the handle number >> TheParms.lHandle = TheHandle >> 'and then exit the function >> GetWindowTitles = 0 >> End If >> >> 'reset to 1 to keep the recursive loop going if not match found >> GetWindowTitles = 1 >> End Function >> >> Private Function TrimNull(ByVal TheText As String) >> 'check to see if string has null characters on the end >> If Not InStr(TheText, Chr$(0)) = 0 Then >> 'if so, then remove the null characters from the end >> TheText = Left$(TheText, InStr(TheText, Chr$(0)) - 1) >> End If >> TrimNull = TheText >> End Function >> ======================================= >> >> Of course the usage of this would be to pass a string to the only >> public function FindWindowByTitle. >> >> Thanks for any light that can be shed on this. >> >> Cory >> > |
|
||
|
||||
|
Jim Cone
Guest
Posts: n/a
|
Cory,
A different approach... Word has a "Tasks" collection that represents all the tasks currently running on the system. You can run code from Excel like this... '-- Sub WhichOnes() Dim objWord As Object Dim objTasks As Object Dim N As Long Set objWord = CreateObject("Word.Application") Set objTasks = objWord.Tasks For N = 1 To objTasks.Count Cells(N, 2).Value = objTasks(N).Name Next 'N Set objTasks = Nothing objWord.Quit Set objWord = Nothing End Sub -- Jim Cone San Francisco, USA http://www.realezsites.com/bus/primitivesoftware (Excel Add-ins / Excel Programming) <(E-Mail Removed)> wrote in message OK, so I'm pretty new to API's so forgive me if this is an idiot question :-) I'm putting together a class that uses API calls to user32 to enumerate and list all running applications by their Title text. One of the functions uses "AddressOf AnotherFunctionName" to accomplish this. The code works fantastic in a module. However, when trying to migrate this to a reusable class, the code crashes on that line with an error of: "Invalid use of AddressOf operator" Looking in Help it says: "You tried to use AddressOf with the name of a class method. Only the names of Visual Basic procedures in a .bas module can be modified with AddressOf. You can't specify a class method." Well, shucks, that just popped my bubble of wanting to make this code really efficient by keeping it in a class amongst some other utility functions I've written. Seems I can only use it in a module instead. My question is this: Is there a way to work around this in a class? Here's my working module code that simply returns a Long greater than zero if an app with all or part of the passed title is found to be running: -snip- Of course the usage of this would be to pass a string to the only public function FindWindowByTitle. Thanks for any light that can be shed on this. Cory |
|
||
|
||||
|
crferguson@gmail.com
Guest
Posts: n/a
|
Thank you very much for your reply. I think I understand where you're
going with this, but I can't seem to get it working. When I add in the FARPROC function and use it per your example, I'm still getting the same error that I originally described: Call EnumWindows(FARPROC(AddressOf GetOpenWindows), VarPtr(tParms)) On Oct 30, 9:45 am, "RB Smissaert" <bartsmissa...@blueyonder.co.uk> wrote: > I forgot to give an example: > > With CC > 'base flag > .flags = CC_ANYCOLOR > .flags = .flags Or CC_FULLOPEN > .flags = .flags Or CC_RGBINIT > .rgbResult = lStartColour > .flags = .flags Or CC_ENABLEHOOK > .lpfnHook = FARPROC(AddressOf ChooseColorProc) > 'size of structure > .lStructSize = Len(CC) > 'assign the custom colour selections > .lpCustColors = VarPtr(dwCustClrs(0)) > End With > > RBS > > "RB Smissaert" <bartsmissa...@blueyonder.co.uk> wrote in message > > news:%(E-Mail Removed)... > > > > > Try this: > > > Instead of calling AddressOf directly call it via a function like this: > > > Function FARPROC(ByVal pfn As Long) As Long > > > FARPROC = pfn > > > End Function > > > RBS > > > <crfergu...@gmail.com> wrote in message > >news:(E-Mail Removed)... > >> OK, so I'm pretty new to API's so forgive me if this is an idiot > >> question :-) > > >> I'm putting together a class that uses API calls to user32 to > >> enumerate and list all running applications by their Title text. One > >> of the functions uses "AddressOf AnotherFunctionName" to accomplish > >> this. The code works fantastic in a module. However, when trying to > >> migrate this to a reusable class, the code crashes on that line with > >> an error of: > > >> "Invalid use of AddressOf operator" > > >> Looking in Help it says: > >> "You tried to use AddressOf with the name of a class method. > >> Only the names of Visual Basic procedures in a .bas module can be > >> modified with AddressOf. You can't specify a class method." > > >> Well, shucks, that just popped my bubble of wanting to make this code > >> really efficient by keeping it in a class amongst some other utility > >> functions I've written. Seems I can only use it in a module instead. > > >> My question is this: Is there a way to work around this in a class? > >> Here's my working module code that simply returns a Long greater than > >> zero if an app with all or part of the passed title is found to be > >> running: > > >> ================================== > >> Option Explicit > > >> Private Declare Function EnumWindows Lib "user32" (ByVal lEnumFunc As > >> Long, ByVal wParam As Long) As Long > > >> Private Declare Function GetWindowText Lib "user32" Alias > >> "GetWindowTextA" _ > >> (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As > >> Long > > >> Private Type AppWindow > >> sTitle As String > >> lHandle As Long > >> End Type > > >> Public Function FindWindowByTitle(ByVal TheWindowTitle As String) As > >> Long > >> 'We'll pass a custom structure in as the parameter to store our > >> result... > >> Dim tParms As AppWindow > >> tParms.sTitle = TheWindowTitle > > >> Call EnumWindows(AddressOf GetWindowTitles, VarPtr(tParms)) > > >> FindWindowByTitle = tParms.lHandle > >> End Function > > >> Private Function GetWindowTitles(ByVal TheHandle As Long, TheParms As > >> AppWindow) As Long > >> Dim sTitleText As String > > >> 'set a generic 260 length empty string to catch the window text > >> sTitleText = Space(260) > >> 'get the text > >> Call GetWindowText(TheHandle, sTitleText, 260) > >> 'remove nulls from the text > >> sTitleText = TrimNull(sTitleText) > > >> 'check to see if all or part of the search string is found > >> 'in the window text > >> If sTitleText Like TheParms.sTitle Then > >> 'if a match is found, then set the handle number > >> TheParms.lHandle = TheHandle > >> 'and then exit the function > >> GetWindowTitles = 0 > >> End If > > >> 'reset to 1 to keep the recursive loop going if not match found > >> GetWindowTitles = 1 > >> End Function > > >> Private Function TrimNull(ByVal TheText As String) > >> 'check to see if string has null characters on the end > >> If Not InStr(TheText, Chr$(0)) = 0 Then > >> 'if so, then remove the null characters from the end > >> TheText = Left$(TheText, InStr(TheText, Chr$(0)) - 1) > >> End If > >> TrimNull = TheText > >> End Function > >> ======================================= > > >> Of course the usage of this would be to pass a string to the only > >> public function FindWindowByTitle. > > >> Thanks for any light that can be shed on this. > > >> Cory- Hide quoted text - > > - Show quoted text - |
|
||
|
||||
|
RB Smissaert
Guest
Posts: n/a
|
I think my solution was for a different problem.
Will have to Google it up. RBS <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > Thank you very much for your reply. I think I understand where you're > going with this, but I can't seem to get it working. When I add in > the FARPROC function and use it per your example, I'm still getting > the same error that I originally described: > > Call EnumWindows(FARPROC(AddressOf GetOpenWindows), VarPtr(tParms)) > > > > > On Oct 30, 9:45 am, "RB Smissaert" <bartsmissa...@blueyonder.co.uk> > wrote: >> I forgot to give an example: >> >> With CC >> 'base flag >> .flags = CC_ANYCOLOR >> .flags = .flags Or CC_FULLOPEN >> .flags = .flags Or CC_RGBINIT >> .rgbResult = lStartColour >> .flags = .flags Or CC_ENABLEHOOK >> .lpfnHook = FARPROC(AddressOf ChooseColorProc) >> 'size of structure >> .lStructSize = Len(CC) >> 'assign the custom colour selections >> .lpCustColors = VarPtr(dwCustClrs(0)) >> End With >> >> RBS >> >> "RB Smissaert" <bartsmissa...@blueyonder.co.uk> wrote in message >> >> news:%(E-Mail Removed)... >> >> >> >> > Try this: >> >> > Instead of calling AddressOf directly call it via a function like this: >> >> > Function FARPROC(ByVal pfn As Long) As Long >> >> > FARPROC = pfn >> >> > End Function >> >> > RBS >> >> > <crfergu...@gmail.com> wrote in message >> >news:(E-Mail Removed)... >> >> OK, so I'm pretty new to API's so forgive me if this is an idiot >> >> question :-) >> >> >> I'm putting together a class that uses API calls to user32 to >> >> enumerate and list all running applications by their Title text. One >> >> of the functions uses "AddressOf AnotherFunctionName" to accomplish >> >> this. The code works fantastic in a module. However, when trying to >> >> migrate this to a reusable class, the code crashes on that line with >> >> an error of: >> >> >> "Invalid use of AddressOf operator" >> >> >> Looking in Help it says: >> >> "You tried to use AddressOf with the name of a class method. >> >> Only the names of Visual Basic procedures in a .bas module can be >> >> modified with AddressOf. You can't specify a class method." >> >> >> Well, shucks, that just popped my bubble of wanting to make this code >> >> really efficient by keeping it in a class amongst some other utility >> >> functions I've written. Seems I can only use it in a module instead. >> >> >> My question is this: Is there a way to work around this in a class? >> >> Here's my working module code that simply returns a Long greater than >> >> zero if an app with all or part of the passed title is found to be >> >> running: >> >> >> ================================== >> >> Option Explicit >> >> >> Private Declare Function EnumWindows Lib "user32" (ByVal lEnumFunc As >> >> Long, ByVal wParam As Long) As Long >> >> >> Private Declare Function GetWindowText Lib "user32" Alias >> >> "GetWindowTextA" _ >> >> (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As >> >> Long >> >> >> Private Type AppWindow >> >> sTitle As String >> >> lHandle As Long >> >> End Type >> >> >> Public Function FindWindowByTitle(ByVal TheWindowTitle As String) As >> >> Long >> >> 'We'll pass a custom structure in as the parameter to store our >> >> result... >> >> Dim tParms As AppWindow >> >> tParms.sTitle = TheWindowTitle >> >> >> Call EnumWindows(AddressOf GetWindowTitles, VarPtr(tParms)) >> >> >> FindWindowByTitle = tParms.lHandle >> >> End Function >> >> >> Private Function GetWindowTitles(ByVal TheHandle As Long, TheParms As >> >> AppWindow) As Long >> >> Dim sTitleText As String >> >> >> 'set a generic 260 length empty string to catch the window text >> >> sTitleText = Space(260) >> >> 'get the text >> >> Call GetWindowText(TheHandle, sTitleText, 260) >> >> 'remove nulls from the text >> >> sTitleText = TrimNull(sTitleText) >> >> >> 'check to see if all or part of the search string is found >> >> 'in the window text >> >> If sTitleText Like TheParms.sTitle Then >> >> 'if a match is found, then set the handle number >> >> TheParms.lHandle = TheHandle >> >> 'and then exit the function >> >> GetWindowTitles = 0 >> >> End If >> >> >> 'reset to 1 to keep the recursive loop going if not match found >> >> GetWindowTitles = 1 >> >> End Function >> >> >> Private Function TrimNull(ByVal TheText As String) >> >> 'check to see if string has null characters on the end >> >> If Not InStr(TheText, Chr$(0)) = 0 Then >> >> 'if so, then remove the null characters from the end >> >> TheText = Left$(TheText, InStr(TheText, Chr$(0)) - 1) >> >> End If >> >> TrimNull = TheText >> >> End Function >> >> ======================================= >> >> >> Of course the usage of this would be to pass a string to the only >> >> public function FindWindowByTitle. >> >> >> Thanks for any light that can be shed on this. >> >> >> Cory- Hide quoted text - >> >> - Show quoted text - > > |
|
||
|
||||
|
crferguson@gmail.com
Guest
Posts: n/a
|
Thank you too for posting that code! That's actually the approach I
was using before, but I found it's not as accurate as I need it to be, which is why I'm trying to tackle it from the API end. With the Word mothod, I had modified it to be able to pass in a string of text and check it against the task collection. If a match was found, then that program is running on the computer. However, the task names don't seem to always be same as the text found in the title of the program's window. I've been running into a situation where users can have three instances of a mainframe program running, all of which have the same process name in Task Manager, but all of which have unique numbered titles (i.e: Session1, Session2, etc...) in the title bar. I've been trying to get that text from the title bar so I can see very specifically which instances they have running. It would be easy to just count how many times the process exists and assume they're numbered 1, 2, 3 etc, but the user can have odd numbered instances such as Session1 and Session4 running, but not Session2 or 3. Does that make sense? I know the Word method should work, but it simply doesn't. I can pass it "*Session1*" and it will return True even if all I have opened is Session3. Weird, but true. Thanks again! Cory On Oct 30, 9:50 am, "Jim Cone" <jim.cone...@rcn.comXXX> wrote: > Cory, > A different approach... > Word has a "Tasks" collection that represents all the tasks currently > running on the system. You can run code from Excel like this... > '-- > Sub WhichOnes() > Dim objWord As Object > Dim objTasks As Object > Dim N As Long > Set objWord = CreateObject("Word.Application") > Set objTasks = objWord.Tasks > For N = 1 To objTasks.Count > Cells(N, 2).Value = objTasks(N).Name > Next 'N > Set objTasks = Nothing > objWord.Quit > Set objWord = Nothing > End Sub > -- > Jim Cone > San Francisco, USAhttp://www.realezsites.com/bus/primitivesoftware > (Excel Add-ins / Excel Programming) > > <crfergu...@gmail.com> > wrote in message > OK, so I'm pretty new to API's so forgive me if this is an idiot > question :-) > I'm putting together a class that uses API calls to user32 to > enumerate and list all running applications by their Title text. One > of the functions uses "AddressOf AnotherFunctionName" to accomplish > this. The code works fantastic in a module. However, when trying to > migrate this to a reusable class, the code crashes on that line with > an error of: > "Invalid use of AddressOf operator" > Looking in Help it says: > "You tried to use AddressOf with the name of a class method. > Only the names of Visual Basic procedures in a .bas module can be > modified with AddressOf. You can't specify a class method." > > Well, shucks, that just popped my bubble of wanting to make this code > really efficient by keeping it in a class amongst some other utility > functions I've written. Seems I can only use it in a module instead. > > My question is this: Is there a way to work around this in a class? > Here's my working module code that simply returns a Long greater than > zero if an app with all or part of the passed title is found to be > running: > -snip- > Of course the usage of this would be to pass a string to the only > public function FindWindowByTitle. > Thanks for any light that can be shed on this. > Cory |
|
||
|
||||
|
crferguson@gmail.com
Guest
Posts: n/a
|
Thanks! I'm doing the same thing. I haven't found anything useful
yet. This would be so much easier if I wasn't limited to VBA. But, it is how it is.... On Oct 30, 11:36 am, "RB Smissaert" <bartsmissa...@blueyonder.co.uk> wrote: > I think my solution was for a different problem. > Will have to Google it up. > > RBS > > <crfergu...@gmail.com> wrote in message > > news:(E-Mail Removed)... > > > > > Thank you very much for your reply. I think I understand where you're > > going with this, but I can't seem to get it working. When I add in > > the FARPROC function and use it per your example, I'm still getting > > the same error that I originally described: > > > Call EnumWindows(FARPROC(AddressOf GetOpenWindows), VarPtr(tParms)) > > > On Oct 30, 9:45 am, "RB Smissaert" <bartsmissa...@blueyonder.co.uk> > > wrote: > >> I forgot to give an example: > > >> With CC > >> 'base flag > >> .flags = CC_ANYCOLOR > >> .flags = .flags Or CC_FULLOPEN > >> .flags = .flags Or CC_RGBINIT > >> .rgbResult = lStartColour > >> .flags = .flags Or CC_ENABLEHOOK > >> .lpfnHook = FARPROC(AddressOf ChooseColorProc) > >> 'size of structure > >> .lStructSize = Len(CC) > >> 'assign the custom colour selections > >> .lpCustColors = VarPtr(dwCustClrs(0)) > >> End With > > >> RBS > > >> "RB Smissaert" <bartsmissa...@blueyonder.co.uk> wrote in message > > >>news:%(E-Mail Removed)... > > >> > Try this: > > >> > Instead of calling AddressOf directly call it via a function like this: > > >> > Function FARPROC(ByVal pfn As Long) As Long > > >> > FARPROC = pfn > > >> > End Function > > >> > RBS > > >> > <crfergu...@gmail.com> wrote in message > >> >news:(E-Mail Removed)... > >> >> OK, so I'm pretty new to API's so forgive me if this is an idiot > >> >> question :-) > > >> >> I'm putting together a class that uses API calls to user32 to > >> >> enumerate and list all running applications by their Title text. One > >> >> of the functions uses "AddressOf AnotherFunctionName" to accomplish > >> >> this. The code works fantastic in a module. However, when trying to > >> >> migrate this to a reusable class, the code crashes on that line with > >> >> an error of: > > >> >> "Invalid use of AddressOf operator" > > >> >> Looking in Help it says: > >> >> "You tried to use AddressOf with the name of a class method. > >> >> Only the names of Visual Basic procedures in a .bas module can be > >> >> modified with AddressOf. You can't specify a class method." > > >> >> Well, shucks, that just popped my bubble of wanting to make this code > >> >> really efficient by keeping it in a class amongst some other utility > >> >> functions I've written. Seems I can only use it in a module instead. > > >> >> My question is this: Is there a way to work around this in a class? > >> >> Here's my working module code that simply returns a Long greater than > >> >> zero if an app with all or part of the passed title is found to be > >> >> running: > > >> >> ================================== > >> >> Option Explicit > > >> >> Private Declare Function EnumWindows Lib "user32" (ByVal lEnumFunc As > >> >> Long, ByVal wParam As Long) As Long > > >> >> Private Declare Function GetWindowText Lib "user32" Alias > >> >> "GetWindowTextA" _ > >> >> (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As > >> >> Long > > >> >> Private Type AppWindow > >> >> sTitle As String > >> >> lHandle As Long > >> >> End Type > > >> >> Public Function FindWindowByTitle(ByVal TheWindowTitle As String) As > >> >> Long > >> >> 'We'll pass a custom structure in as the parameter to store our > >> >> result... > >> >> Dim tParms As AppWindow > >> >> tParms.sTitle = TheWindowTitle > > >> >> Call EnumWindows(AddressOf GetWindowTitles, VarPtr(tParms)) > > >> >> FindWindowByTitle = tParms.lHandle > >> >> End Function > > >> >> Private Function GetWindowTitles(ByVal TheHandle As Long, TheParms As > >> >> AppWindow) As Long > >> >> Dim sTitleText As String > > >> >> 'set a generic 260 length empty string to catch the window text > >> >> sTitleText = Space(260) > >> >> 'get the text > >> >> Call GetWindowText(TheHandle, sTitleText, 260) > >> >> 'remove nulls from the text > >> >> sTitleText = TrimNull(sTitleText) > > >> >> 'check to see if all or part of the search string is found > >> >> 'in the window text > >> >> If sTitleText Like TheParms.sTitle Then > >> >> 'if a match is found, then set the handle number > >> >> TheParms.lHandle = TheHandle > >> >> 'and then exit the function > >> >> GetWindowTitles = 0 > >> >> End If > > >> >> 'reset to 1 to keep the recursive loop going if not match found > >> >> GetWindowTitles = 1 > >> >> End Function > > >> >> Private Function TrimNull(ByVal TheText As String) > >> >> 'check to see if string has null characters on the end > >> >> If Not InStr(TheText, Chr$(0)) = 0 Then > >> >> 'if so, then remove the null characters from the end > >> >> TheText = Left$(TheText, InStr(TheText, Chr$(0)) - 1) > >> >> End If > >> >> TrimNull = TheText > >> >> End Function > >> >> ======================================= > > >> >> Of course the usage of this would be to pass a string to the only > >> >> public function FindWindowByTitle. > > >> >> Thanks for any light that can be shed on this. > > >> >> Cory- Hide quoted text - > > >> - Show quoted text -- Hide quoted text - > > - Show quoted text - |
|
||
|
||||
|
RB Smissaert
Guest
Posts: n/a
|
Not sure it can work in VBA, but this link addresses the problem:
http://shorterlink.com/?DM71M6 RBS <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > Thanks! I'm doing the same thing. I haven't found anything useful > yet. This would be so much easier if I wasn't limited to VBA. But, > it is how it is.... > > On Oct 30, 11:36 am, "RB Smissaert" <bartsmissa...@blueyonder.co.uk> > wrote: >> I think my solution was for a different problem. >> Will have to Google it up. >> >> RBS >> >> <crfergu...@gmail.com> wrote in message >> >> news:(E-Mail Removed)... >> >> >> >> > Thank you very much for your reply. I think I understand where you're >> > going with this, but I can't seem to get it working. When I add in >> > the FARPROC function and use it per your example, I'm still getting >> > the same error that I originally described: >> >> > Call EnumWindows(FARPROC(AddressOf GetOpenWindows), VarPtr(tParms)) >> >> > On Oct 30, 9:45 am, "RB Smissaert" <bartsmissa...@blueyonder.co.uk> >> > wrote: >> >> I forgot to give an example: >> >> >> With CC >> >> 'base flag >> >> .flags = CC_ANYCOLOR >> >> .flags = .flags Or CC_FULLOPEN >> >> .flags = .flags Or CC_RGBINIT >> >> .rgbResult = lStartColour >> >> .flags = .flags Or CC_ENABLEHOOK >> >> .lpfnHook = FARPROC(AddressOf ChooseColorProc) >> >> 'size of structure >> >> .lStructSize = Len(CC) >> >> 'assign the custom colour selections >> >> .lpCustColors = VarPtr(dwCustClrs(0)) >> >> End With >> >> >> RBS >> >> >> "RB Smissaert" <bartsmissa...@blueyonder.co.uk> wrote in message >> >> >>news:%(E-Mail Removed)... >> >> >> > Try this: >> >> >> > Instead of calling AddressOf directly call it via a function like >> >> > this: >> >> >> > Function FARPROC(ByVal pfn As Long) As Long >> >> >> > FARPROC = pfn >> >> >> > End Function >> >> >> > RBS >> >> >> > <crfergu...@gmail.com> wrote in message >> >> >news:(E-Mail Removed)... >> >> >> OK, so I'm pretty new to API's so forgive me if this is an idiot >> >> >> question :-) >> >> >> >> I'm putting together a class that uses API calls to user32 to >> >> >> enumerate and list all running applications by their Title text. >> >> >> One >> >> >> of the functions uses "AddressOf AnotherFunctionName" to accomplish >> >> >> this. The code works fantastic in a module. However, when trying >> >> >> to >> >> >> migrate this to a reusable class, the code crashes on that line >> >> >> with >> >> >> an error of: >> >> >> >> "Invalid use of AddressOf operator" >> >> >> >> Looking in Help it says: >> >> >> "You tried to use AddressOf with the name of a class method. >> >> >> Only the names of Visual Basic procedures in a .bas module can be >> >> >> modified with AddressOf. You can't specify a class method." >> >> >> >> Well, shucks, that just popped my bubble of wanting to make this >> >> >> code >> >> >> really efficient by keeping it in a class amongst some other >> >> >> utility >> >> >> functions I've written. Seems I can only use it in a module >> >> >> instead. >> >> >> >> My question is this: Is there a way to work around this in a class? >> >> >> Here's my working module code that simply returns a Long greater >> >> >> than >> >> >> zero if an app with all or part of the passed title is found to be >> >> >> running: >> >> >> >> ================================== >> >> >> Option Explicit >> >> >> >> Private Declare Function EnumWindows Lib "user32" (ByVal lEnumFunc >> >> >> As >> >> >> Long, ByVal wParam As Long) As Long >> >> >> >> Private Declare Function GetWindowText Lib "user32" Alias >> >> >> "GetWindowTextA" _ >> >> >> (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) >> >> >> As >> >> >> Long >> >> >> >> Private Type AppWindow >> >> >> sTitle As String >> >> >> lHandle As Long >> >> >> End Type >> >> >> >> Public Function FindWindowByTitle(ByVal TheWindowTitle As String) >> >> >> As >> >> >> Long >> >> >> 'We'll pass a custom structure in as the parameter to store our >> >> >> result... >> >> >> Dim tParms As AppWindow >> >> >> tParms.sTitle = TheWindowTitle >> >> >> >> Call EnumWindows(AddressOf GetWindowTitles, VarPtr(tParms)) >> >> >> >> FindWindowByTitle = tParms.lHandle >> >> >> End Function >> >> >> >> Private Function GetWindowTitles(ByVal TheHandle As Long, TheParms >> >> >> As >> >> >> AppWindow) As Long >> >> >> Dim sTitleText As String >> >> >> >> 'set a generic 260 length empty string to catch the window text >> >> >> sTitleText = Space(260) >> >> >> 'get the text >> >> >> Call GetWindowText(TheHandle, sTitleText, 260) >> >> >> 'remove nulls from the text >> >> >> sTitleText = TrimNull(sTitleText) >> >> >> >> 'check to see if all or part of the search string is found >> >> >> 'in the window text >> >> >> If sTitleText Like TheParms.sTitle Then >> >> >> 'if a match is found, then set the handle number >> >> >> TheParms.lHandle = TheHandle >> >> >> 'and then exit the function >> >> >> GetWindowTitles = 0 >> >> >> End If >> >> >> >> 'reset to 1 to keep the recursive loop going if not match found >> >> >> GetWindowTitles = 1 >> >> >> End Function >> >> >> >> Private Function TrimNull(ByVal TheText As String) >> >> >> 'check to see if string has null characters on the end >> >> >> If Not InStr(TheText, Chr$(0)) = 0 Then >> >> >> 'if so, then remove the null characters from the end >> >> >> TheText = Left$(TheText, InStr(TheText, Chr$(0)) - 1) >> >> >> End If >> >> >> TrimNull = TheText >> >> >> End Function >> >> >> ======================================= >> >> >> >> Of course the usage of this would be to pass a string to the only >> >> >> public function FindWindowByTitle. >> >> >> >> Thanks for any light that can be shed on this. >> >> >> >> Cory- Hide quoted text - >> >> >> - Show quoted text -- Hide quoted text - >> >> - Show quoted text - > > |
|
||
|
||||
|
Peter T
Guest
Posts: n/a
|
Hi Cory,
Before seeing the link referred to by RBS I would have said no way to call a procedure in a class module with AddressOf. However perhaps the Implements approach might work, I haven't tried. If all you want is to return a list of window handles and captions try the 'mySpy' routine here - http://tinyurl.com/28ufpp Ignore the preamble and discard Test2(), paste all into a normal module and run the Test() example on a clean sheet. The routine produces a tree like array of hWin's & titles 'ArrWins' and, as written, dumps this into cells (guess you won't need that bit). It should be easy to adapt to entirely to class based and use ArrWin as required. In theory the recursive Find-next approach is not as reliable as EnumWindows, eg if during the process a window is closed it would halt. However for most purposes should be pretty fast and 'almost' always complete. Regards, Peter T <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > OK, so I'm pretty new to API's so forgive me if this is an idiot > question :-) > > I'm putting together a class that uses API calls to user32 to > enumerate and list all running applications by their Title text. One > of the functions uses "AddressOf AnotherFunctionName" to accomplish > this. The code works fantastic in a module. However, when trying to > migrate this to a reusable class, the code crashes on that line with > an error of: > > "Invalid use of AddressOf operator" > > Looking in Help it says: > "You tried to use AddressOf with the name of a class method. > Only the names of Visual Basic procedures in a .bas module can be > modified with AddressOf. You can't specify a class method." > > Well, shucks, that just popped my bubble of wanting to make this code > really efficient by keeping it in a class amongst some other utility > functions I've written. Seems I can only use it in a module instead. > > My question is this: Is there a way to work around this in a class? > Here's my working module code that simply returns a Long greater than > zero if an app with all or part of the passed title is found to be > running: > > ================================== > Option Explicit > > Private Declare Function EnumWindows Lib "user32" (ByVal lEnumFunc As > Long, ByVal wParam As Long) As Long > > Private Declare Function GetWindowText Lib "user32" Alias > "GetWindowTextA" _ > (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As > Long > > Private Type AppWindow > sTitle As String > lHandle As Long > End Type > > Public Function FindWindowByTitle(ByVal TheWindowTitle As String) As > Long > 'We'll pass a custom structure in as the parameter to store our > result... > Dim tParms As AppWindow > tParms.sTitle = TheWindowTitle > > Call EnumWindows(AddressOf GetWindowTitles, VarPtr(tParms)) > > FindWindowByTitle = tParms.lHandle > End Function > > Private Function GetWindowTitles(ByVal TheHandle As Long, TheParms As > AppWindow) As Long > Dim sTitleText As String > > 'set a generic 260 length empty string to catch the window text > sTitleText = Space(260) > 'get the text > Call GetWindowText(TheHandle, sTitleText, 260) > 'remove nulls from the text > sTitleText = TrimNull(sTitleText) > > 'check to see if all or part of the search string is found > 'in the window text > If sTitleText Like TheParms.sTitle Then > 'if a match is found, then set the handle number > TheParms.lHandle = TheHandle > 'and then exit the function > GetWindowTitles = 0 > End If > > 'reset to 1 to keep the recursive loop going if not match found > GetWindowTitles = 1 > End Function > > Private Function TrimNull(ByVal TheText As String) > 'check to see if string has null characters on the end > If Not InStr(TheText, Chr$(0)) = 0 Then > 'if so, then remove the null characters from the end > TheText = Left$(TheText, InStr(TheText, Chr$(0)) - 1) > End If > TrimNull = TheText > End Function > ======================================= > > Of course the usage of this would be to pass a string to the only > public function FindWindowByTitle. > > Thanks for any light that can be shed on this. > > Cory > |
|
||
|
||||
|
|
|
| |
![]() |
| Thread Tools | |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Inheritance question: How to instantiate derived class from base class | Anthony Greene | Microsoft C# .NET | 15 | 7th Mar 2007 04:11 PM |
| Question regarding initializing base class object to derived class object, | archana | Microsoft C# .NET | 1 | 9th Jan 2007 07:50 AM |
| call a mnuFileNew_Click method from a Main MDI class from another class (can be a MdiChild class.. )? | M. G, | Microsoft Dot NET Framework Forms | 1 | 31st May 2006 06:28 AM |
| Serailize RCW class OR IPersistStream call to RCW class question | Chris Puncher | Microsoft ASP .NET | 2 | 20th Jan 2005 09:59 AM |
| activex ,money tree dialer,RdxE Class,updaate class,YInstStarter Class damaged | RUSSELL | Windows XP Performance | 1 | 23rd Nov 2003 02:05 PM |
Powered by vBulletin®. Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2010, Crawlability, Inc. |




