Page 1 of 2

sendgadgetcommand

Posted: Fri Oct 14, 2011 11:16 am
by t57042

Code: Select all

Import "gadget.lib"
      PB_Gadget_SendGadgetCommand(hWnd, EventType)
    EndImport
.
.
  PB_Gadget_SendGadgetCommand(GadgetID(1), #PB_EventType_LeftClick)
 
With the code above, the button initialised by gadget 1 is left clicked. This is within 1 window.
How can this be modified to click a button in another window (another application)?

Autowin or autoit both can do it. But it is more simple just to have the one function.

Richard

Re: sendgadgetcommand

Posted: Fri Oct 14, 2011 11:31 am
by netmaestro
You would first get the hwnd of the window containing the button, then EnumChildWindows_() on that hwnd and in your callback do GetClassName_() on all the childs to pick out the buttons and for those do GetWindowText_() to isolate the target button. Once you've done that, do a SetActiveWindow_() on the containing window, SendMessage_(<button hwnd>, #BM_CLICK, 0,0) and you're done. PB_SendGadgetCommand is an internal of Purebasic not really intended for coders to use and it will only affect local self-created gadgets.

Re: sendgadgetcommand

Posted: Fri Oct 14, 2011 11:34 am
by t57042
Sorry, but is all to complicated for me.
Can you give an example?

Thanks
Richard

Re: sendgadgetcommand

Posted: Fri Oct 14, 2011 11:49 am
by ts-soft
t57042 wrote:Sorry, but is all to complicated for me.
Can you give an example?
What netmaestro says is that, what autowin do :mrgreen:

Re: sendgadgetcommand

Posted: Fri Oct 14, 2011 5:49 pm
by netmaestro
Sorry, but is all to complicated for me.
Can you give an example?
Reading it over, I guess it does sound complicated and hard to do. But the reality is that it's quite straightforward:

Code: Select all

Global NewMap keys.i(50)

Procedure Enum(hwnd, lparam)
  searchstring$ = "0123456789.+-*/="
  cn$ = Space(#MAX_PATH)
  wn$ = Space(#MAX_PATH)
  GetClassName_(hwnd, @cn$, #MAX_PATH)
  If UCase(cn$) = "BUTTON"
    GetWindowText_(hwnd, @wn$, #MAX_PATH)
    loc = FindString(searchstring$, wn$)
    If loc
      keys(wn$) = hwnd
    EndIf
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure SendVisibleClick(button)
  SendMessage_(button, #WM_LBUTTONDOWN, 0,0)
  Delay(300)
  SendMessage_(button, #WM_LBUTTONUP, 0,0)
EndProcedure

If Not calc
  RunProgram("calc.exe")
  Delay(300)
  calc = FindWindow_("CalcFrame", 0)
  If Not calc
    calc = FindWindow_("SciCalc", 0)
  EndIf
EndIf

EnumChildWindows_(calc, @Enum(), 0)

SetActiveWindow_(calc)
Delay(500)

SendVisibleClick(keys("2"))
SendVisibleClick(keys("+"))
SendVisibleClick(keys("2"))
SendVisibleClick(keys("="))
This sample sends buttonclicks that are happening in a way visible to the user. To send "silent" clicks, remove the delay from SendVisibleClick or simpy send the #BM_CLICK message.

Re: sendgadgetcommand

Posted: Fri Oct 14, 2011 6:59 pm
by t57042
I tried the sample, and at first I had a syntaxerror:

Code: Select all

loc = FindString(searchstring$, wn$,1)
The 3d parameter was missing.
Then it runs... but nothin visibly happens.
I am running Windows 7 and PB version 4.51


Richard

Re: sendgadgetcommand

Posted: Fri Oct 14, 2011 7:58 pm
by RASHAD
netmaestro explained to you the right method
Search the forum for digger by netmaestro you will need it

Next is for Win 7 by using the Window ID

Code: Select all

Global Dim nkHwnd(10)
Global Dim fkHwnd(4)

Procedure Enum(hwnd, lparam)  
  bHwnd = GetWindow_(hwnd, #GW_HWNDNEXT)
  wID = GetWindowLongPtr_(bHwnd,#GWL_ID)
  If wID >= 91 And wID <= 94  
    fkHwnd(wID-90) = bHwnd
  ElseIf wID = 121
    fkHwnd(0) = bHwnd
  ElseIf wID >= 130 And wID <= 139
    nkHwnd(wID-130) = bHwnd    
  EndIf
 ProcedureReturn #True
EndProcedure

Procedure SendVisibleClick(button)
  SendMessage_(button, #WM_LBUTTONDOWN, 0,0)
  Delay(300)
  SendMessage_(button, #WM_LBUTTONUP, 0,0)
EndProcedure

If Not calc
  RunProgram("calc.exe")
  Delay(300)
  calc = FindWindow_("CalcFrame", 0)
EndIf

EnumChildWindows_(calc, @Enum(), 0)

SetActiveWindow_(calc)
Delay(500)

SendVisibleClick(nkHwnd(2))
SendVisibleClick(fkHwnd(3))
SendVisibleClick(nkHwnd(2))
SendVisibleClick(fkHwnd(0))

The following is for XP using netmaestro code

Code: Select all

Global NewMap keys.i(50)

Procedure Enum(hwnd, lparam)
  searchstring$ = "0123456789.+-*/="
  cn$ = Space(#MAX_PATH)
  wn$ = Space(#MAX_PATH)
  GetClassName_(hwnd, @cn$, #MAX_PATH)
  If UCase(cn$) = "BUTTON"
    GetWindowText_(hwnd, @wn$, #MAX_PATH)
    loc = FindString(searchstring$, wn$)
    If loc
      keys(wn$) = hwnd
    EndIf
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure SendVisibleClick(button)
  SendMessage_(button, #WM_LBUTTONDOWN, 0,0)
  Delay(300)
  SendMessage_(button, #WM_LBUTTONUP, 0,0)
EndProcedure

If Not calc
  RunProgram("calc.exe")
  Delay(300)
  calc = FindWindow_("SciCalc", 0)
EndIf

EnumChildWindows_(calc, @Enum(), 0)

SetActiveWindow_(calc)
Delay(500)

SendVisibleClick(keys("2"))
SendVisibleClick(keys("+"))
SendVisibleClick(keys("2"))
SendVisibleClick(keys("="))


Re: sendgadgetcommand

Posted: Fri Oct 14, 2011 8:35 pm
by c4s
t57042 wrote:I tried the sample, and at first I had a syntaxerror:

Code: Select all

loc = FindString(searchstring$, wn$,1)
The 3d parameter was missing.
That's because with 4.60 Beta the last parameter is optional (defaults to "1").

Re: sendgadgetcommand

Posted: Sat Oct 15, 2011 10:32 am
by t57042
I am trying to simplify the code, since I have only 1 button in the program I call - but I don't succeed.

Code: Select all

    Global Dim nkHwnd(20)
    Global Dim fkHwnd(14)

    Procedure Enum(hwnd, lparam) 
      bHwnd = GetWindow_(hwnd, #GW_HWNDNEXT)
      wID = GetWindowLongPtr_(bHwnd,#GWL_ID)
      If wID >= 91 And wID <= 94 
       fkHwnd(wID-90) = bHwnd
      ElseIf wID = 121
        fkHwnd(0) = bHwnd
      ElseIf wID >= 130 And wID <= 139
        nkHwnd(wID-130) = bHwnd   
      EndIf
      
    ProcedureReturn #True
    EndProcedure

    
    If Not calc
      RunProgram("recmes2.exe")
      Delay(300)
      calc = FindWindow_("test", 0)
    EndIf

    EnumChildWindows_(calc, @Enum(), 0)

    SetActiveWindow_(calc)
    Delay(500)

    SendMessage_(nkHwnd(4), #WM_LBUTTONDOWN, 0,0)
    SendMessage_(nkHwnd(4), #WM_LBUTTONUP, 0,0)
    
This is the (test)program I call:

Code: Select all

If OpenWindow(0, 0, 0, 230, 90, "test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   ButtonGadget  (1, 10, 10, 200, 20, "1")   
   Repeat
     Event = WaitWindowEvent()
     Select Event
       Case #PB_Event_Gadget
         Select EventGadget()
           Case 1 : Debug "Button 1 clicked!"         
         EndSelect
     EndSelect
   Until Event = #PB_Event_CloseWindow
 EndIf
Thanks for the help
Richard

Re: sendgadgetcommand

Posted: Sat Oct 15, 2011 12:20 pm
by RASHAD
@t57042 Hi
That code is specially for "Calc.exe" and Win 7

You got to know how to get the Handle of the requested object
It could be by ClassName ,Window Text,Window ID ......
Here we will get the handle by using Window Text, in this case "1"

Code: Select all


Global gWnd

Procedure Enum(hwnd, lparam)
    wn$ = Space(#MAX_PATH)
    GetWindowText_(hwnd, @wn$, #MAX_PATH)
    If wn$ = "1"
      gWnd = hwnd
    EndIf      
  ProcedureReturn #True
EndProcedure

Procedure SendVisibleClick(button)
  SendMessage_(button, #WM_LBUTTONDOWN, 0,0)
  Delay(300)
  SendMessage_(button, #WM_LBUTTONUP, 0,0)
EndProcedure

  RunProgram("recmes2.exe")
  Delay(300)
  hWnd = FindWindow_(0,"test")

EnumChildWindows_(hWnd, @Enum(), 0)

SetActiveWindow_(hWnd)
Delay(500)

SendVisibleClick(gWnd)
Compile the next as "recmes2.exe"
Then run the first snippet

Code: Select all

If OpenWindow(0, 0, 0, 230, 90, "test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   ButtonGadget  (1, 10, 10, 200, 20, "1")   
   Repeat
     Event = WaitWindowEvent()
     Select Event
       Case #PB_Event_Gadget
         Select EventGadget()
           Case 1 : MessageRequester("Note :","Button 1 clicked!",#MB_ICONWARNING)    
         EndSelect
     EndSelect
   Until Event = #PB_Event_CloseWindow
EndIf

Re: sendgadgetcommand

Posted: Sat Oct 15, 2011 12:33 pm
by t57042
This works but why the added #MB_ICONWARNING in the messagerequester?

The final purpose is not to display a messagerequester but to execute some code upon reception of the button click.

Richard

Re: sendgadgetcommand

Posted: Sat Oct 15, 2011 1:57 pm
by RASHAD
This works but why the added #MB_ICONWARNING in the messagerequester?
:mrgreen: This is one of the negatives of copy and paste
You can delete #MB_ICONWARNING

You can do any PB command but not Debug in exe that is why I replaced Debug by messagerequester

Re: sendgadgetcommand

Posted: Sat Oct 15, 2011 3:07 pm
by t57042
This is one of the negatives of copy and paste
I want to send a string to the other program, which is waiting in an eventloop.
Then the buttonclick is sended to warn the program a string has been send.

Is there a better way to accomplish what I want?

Richard

Re: sendgadgetcommand

Posted: Sat Oct 15, 2011 3:48 pm
by ts-soft
see here
or here, but in german :mrgreen:

Re: sendgadgetcommand

Posted: Sat Oct 15, 2011 4:01 pm
by t57042
What if the receiver is not a PB program?