Enhanced FindWindow for variable window class names: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
m (Adding new author and category links.)
No edit summary
 
(9 intermediate revisions by 5 users not shown)
Line 2: Line 2:


== Introduction ==
== Introduction ==
Sometimes, you want to send messages to a window, that you don't know the full window class name (wcn) of, or it contains variables and you know the constant part. So you can't use FindWindow, that doesn't support wildcars.
Sometimes, you want to send messages to a window, that you don't know the full window class name (wcn) of, or it contains variables and you know the constant part. So you can't use FindWindow because it doesn't support wildcards.
This function doesn't too. But you can get the handle of any window, whith only one known part of the wcn.
This function doesn't too. But you can get the handle of any window, with only one known part of the wcn.


== Usage ==
== Usage ==
Simply call this function. At the moment, all variables are hardcoded, so you don't have to push anything. Maybe, i'll add this possibility later.
<highlight-nsis>
<highlight-nsis>
Push  "Application"   # the known part of the wcn
Push  0   # the starting offset of the push below
Push  0   # the starting offset of the upper push
Push  "Application"   # the known part of the class name
Call  EnhancedFindWindow
Call  EnhancedFindWindow
Pop  $0  # will contain the window's handle
Pop  $0  # will contain the full wcn
Pop  $1  # will containg the full wcn
Pop  $1  # will contain the window's handle
           # both will containg "failed", if no matching wcn was found
           # both will contain "failed", if no matching class name was found
</highlight-nsis>
</highlight-nsis>


Line 20: Line 19:
Function  EnhancedFindWindow
Function  EnhancedFindWindow
   ; input, save variables
   ; input, save variables
   Exch  $0  # part of the wcn to search for
   Exch  $0  # part of the class name to search for
   Exch
   Exch
   Exch  $1  # starting offset
   Exch  $1  # starting offset
   Push  $2  # length of $0
   Push  $2  # length of $0
   Push  $3   # return code
   Push  $3  # window handle
  Push  $4   # window handle
   Push  $4   # class name
   Push  $5   # returned class name
   Push  $5   # temp
   Push  $6   # max length of $5


   ; set up the variables
   ; set up the variables
  SetPluginUnload  alwaysoff    # recommended, if u're using the \
   StrCpy  $4  0
                                  system plugin
   StrLen $2  $0
   StrCpy  $4  0                 # FindWindow wouldn't work without
   StrCpy $2  ${NSIS_MAX_STRLEN} # the max length of string variables
  StrLen  $5  $4                # it's length


  ; loop to search for open windows
  ; loop to search for open windows
  search_loop:
  search_loop:
   FindWindow  $4 ""  ""  0  $4
   FindWindow  $3 ""  ""  0  $3
   IntCmp  $4 0  search_failed
   IntCmp  $3 0  search_failed
     IsWindow  $4 search_failed
     IsWindow  $3 search_loop
     System::Call \
     System::Call 'user32.dll::GetClassName(i r3, t .r4, i ${NSIS_MAX_STRLEN}) i .n'
      'user32.dll::GetClassName(i, t, *i) i(r4r4, .r5, r6r6) .r3'
     StrCmp $4 0  search_loop
     IntCmp $3 0  search_loop
    StrCpy  $5  $4 $2  $1
      StrCpy  $3  $5
    StrCmp  $0  $5  search_end  search_loop
      StrCpy  $5  $5 $2  $1
      StrCmp  $0  $5  search_end  search_loop


  ; no matching class-name found, return "failed"
  ; no matching class-name found, return "failed"
  search_failed:
  search_failed:
  StrCpy  $3  "failed"
   StrCpy  $4  "failed"
   StrCpy  $4  "failed"
  StrCpy  $3  "failed"


  ; search ended, output and restore variables
  ; search ended, output and restore variables
  search_end:
  search_end:
  SetPluginUnload  manual  # the system-plugin can now unload itself
  System::Free  0          # free the memory
   StrCpy  $1  $3
   StrCpy  $1  $3
   StrCpy  $0  $4
   StrCpy  $0  $4
  Pop  $6
   Pop  $5
   Pop  $5
   Pop  $4
   Pop  $4

Latest revision as of 13:29, 12 February 2011

Author: Comm@nder21 (talk, contrib)


Introduction

Sometimes, you want to send messages to a window, that you don't know the full window class name (wcn) of, or it contains variables and you know the constant part. So you can't use FindWindow because it doesn't support wildcards. This function doesn't too. But you can get the handle of any window, with only one known part of the wcn.

Usage

Push  0   # the starting offset of the push below
Push  "Application"   # the known part of the class name
Call  EnhancedFindWindow
Pop  $0   # will contain the full wcn
Pop  $1   # will contain the window's handle
          # both will contain "failed", if no matching class name was found

The Function

Function  EnhancedFindWindow
  ; input, save variables
  Exch  $0   # part of the class name to search for
  Exch
  Exch  $1   # starting offset
  Push  $2   # length of $0
  Push  $3   # window handle
  Push  $4   # class name
  Push  $5   # temp
 
  ; set up the variables
  StrCpy  $4  0
  StrLen  $2  $0
 
 ; loop to search for open windows
 search_loop:
  FindWindow  $3  ""  ""  0  $3
   IntCmp  $3  0  search_failed
    IsWindow  $3  0  search_loop
     System::Call 'user32.dll::GetClassName(i r3, t .r4, i ${NSIS_MAX_STRLEN}) i .n'
     StrCmp  $4  0  search_loop
     StrCpy  $5  $4  $2  $1
     StrCmp  $0  $5  search_end  search_loop
 
 ; no matching class-name found, return "failed"
 search_failed:
  StrCpy  $3  "failed"
  StrCpy  $4  "failed"
 
 ; search ended, output and restore variables
 search_end:
  StrCpy  $1  $3
  StrCpy  $0  $4
  Pop  $5
  Pop  $4
  Pop  $3
  Pop  $2
  Exch  $1
  Exch
  Exch  $0
FunctionEnd

Feedback

Any suggestions, feature requests or even bug reports? Feel free to send me an email or a private message.

Please post any other question, e.g. about usage and customization at the NSIS forums. Remember: You're not alone ...

Further Reading

See this topic for more information about the function itself and alternatives. See the msdn for more information about the user32 api call "GetClassName".