Page 2 of 2

Posted: Thu Jun 14, 2007 4:20 pm
by ricardo
This is more or less the way that plugins works in winamp.
The SDK dont provide a direct way to add buttons or menu tiems, so you need to do more or less this same thing.
To avoid that all crashes when user close winamp you need to detect when user is closing and take out your process from the queue.

Posted: Sat Jun 16, 2007 10:46 am
by Michael Vogel
Hey - what a cool idea!

just bad, that the content of elements from other applications can't be read (at least in Win 2k).

I did just two more modifications...

* Case #WM_NCDESTROY,#WM_DESTROY
so Alt-F4 will also close the program now...

* GetWindowRect_(WinHandle,@winrect) [...]
put the new button to the left side now, the position seems to be not very accurate...

Michael

Code: Select all

; Define
	Global oldproc,quit=0,backbutton,cebutton,clearbutton,one,two,three
	Global four,five,six,seven,eight,nine,zero,point
	Global winrect.RECT
; EndDefine
Procedure ButtonProc(hwnd,msg,wParam,lParam)
	Select msg
	Case #WM_NCDESTROY,#WM_DESTROY
		End
	Case #WM_LBUTTONUP
		SendMessage_(cebutton,#BM_CLICK,0,0)
		SendMessage_(three,   #BM_CLICK,0,0)
		SendMessage_(point,   #BM_CLICK,0,0)
		SendMessage_(one,     #BM_CLICK,0,0)
		SendMessage_(four,    #BM_CLICK,0,0)
		SendMessage_(one,     #BM_CLICK,0,0)
		SendMessage_(five,    #BM_CLICK,0,0)
		SendMessage_(nine,    #BM_CLICK,0,0)
		SendMessage_(two,    #BM_CLICK,0,0)
		SendMessage_(six,    #BM_CLICK,0,0)
		SendMessage_(five,    #BM_CLICK,0,0)
	EndSelect
	ProcedureReturn CallWindowProc_(oldproc,hwnd,msg,wParam,lParam)
EndProcedure
Procedure GetClearButtons(hwnd,param)
	CtrlID=GetDlgCtrlID_(hwnd)

	Select CtrlID
	Case 81
		clearbutton=hwnd
	Case 82
		cebutton=hwnd
	Case 83
		backbutton=hwnd
	EndSelect
	ProcedureReturn 1
EndProcedure
Procedure GetNumbers(hwnd,param)
	Select GetDlgCtrlID_(hwnd)
	Case 124 : zero=hwnd
	Case 125 : one=hwnd
	Case 126 : two=hwnd
	Case 127 : three=hwnd
	Case 128 : four=hwnd
	Case 129 : five=hwnd
	Case 130 : six=hwnd
	Case 131 : seven=hwnd
	Case 132 : eight=hwnd
	Case 133 : nine=hwnd
	Case 85 : point=hwnd
	EndSelect
	ProcedureReturn 1
EndProcedure
Procedure Init()

	CalcProgramID=RunProgram("Calc.Exe","","",#PB_Program_Open)

	If CalcProgramID
		CalcProcessID=ProgramID(CalcProgramID)
		Count=0
		Repeat
			Delay(100)          ; Avoid hanging of windows during start of application while searching for the window
			Count=Count + 1   ; Security counter to avoid hanging
			WinHandle=FindWindow_(0,0)
			While WinHandle <> 0
				GetWindowThreadProcessId_(WinHandle,@ProcessID)
				If ProcessID=CalcProcessID
					c=WinHandle
					Break
				EndIf
				WinHandle=GetWindow_(WinHandle,#GW_HWNDNEXT)
			Wend
		Until c Or (Count=50) ; Wait up to 5 seconds for window to occur
	EndIf

	If c
		EnumChildWindows_(c,@GetClearButtons(),0)
		EnumChildWindows_(c,@GetNumbers(),0)
		;SetWindowPos_(clearbutton,0,0,0,28,29,#SWP_NOZORDER|#SWP_NOMOVE|#SWP_FRAMECHANGED)

		InitCommonControls_()
		GetWindowRect_(c,@cr.RECT)
		w=cr\right-cr\left
		If w<270 ; Standard
			If OSVersion()=#PB_OS_Windows_NT_4
				yPosPIButton=46
			Else
				yPosPIButton=37
			EndIf

			GetWindowRect_(WinHandle,@winrect)
			x=winrect\left+2;???
			y=winrect\top+yPosPIButton+2;???
			GetWindowRect_(backbutton,@winrect)
			winrect\bottom-winrect\top
			winrect\right-winrect\left
			winrect\left-x
			winrect\top-y
			SetWindowPos_(backbutton,0,winrect\left+30,winrect\top,34,winrect\bottom,#SWP_NOZORDER|#SWP_FRAMECHANGED)
			button=CreateWindowEx_(0,"Button","PI",#WS_CHILD|#WS_VISIBLE,winrect\left,winrect\top,28,winrect\bottom,c,0,GetModuleHandle_(0),0)

		EndIf
		RedrawWindow_(button,0,0,#RDW_UPDATENOW)
	Else
		MessageRequester("OOPS!","Can't find the Calculator!",#MB_ICONERROR)
		End
	EndIf

	oldproc=SetWindowLong_(button,#GWL_WNDPROC,@ButtonProc())

EndProcedure

Init()

result=GetMessage_(@msg.MSG,#Null,#Null,#Null)
While result<>0
	If result=-1 ; GetMessage failed
		MessageRequester("OOPS!","Failure in GetMessage Loop",#MB_ICONERROR)
		End
	EndIf
	TranslateMessage_(msg)
	DispatchMessage_(msg)
	result=GetMessage_(@msg.MSG,#Null,#Null,#Null)
Wend

Re: Win API: Add a control to an unowned application

Posted: Wed May 15, 2013 8:01 pm
by Psychophanta
Is there any other way to get the app title (caption) which works in win 7?

Re: Win API: Add a control to an unowned application

Posted: Sun Jun 16, 2013 10:48 pm
by em_uk
Do you mean find the Window Title?

Code: Select all

Structure FindWindowData
  hFW.l ; variable to store a handle
  sFW.s ; variable to store a Window name
  cFW.s ; variable to store a window class name
EndStructure

Global NewList WindowList.FindWindowData()

Procedure.l EnumWindowsCallBack(hFind, lParam)
  WindowName.s = Space(255)
  WindowClass.s = Space(255)
  If GetWindowText_(hFind, WindowName, 255)
    Result = GetClassName_(hFind, WindowClass, 255)
    AddElement(WindowList())
    WindowList()\hFW = hFind
    WindowList()\sFW = WindowName
    WindowList()\cFW = WindowClass
  EndIf
  
  ProcedureReturn #True
  
EndProcedure

Window$=LCase("Purebasic")

If EnumWindows_(@EnumWindowsCallBack(), 0)
  ResetList(WindowList())
  While NextElement(WindowList())
    Debug("Window: " + WindowList()\sFW)
    If FindString(LCase(WindowList()\sFW), Window$, 1)
      Found$=(WindowList()\sFW)
      Debug "------- Found Our Window ---------"
      Debug "hwd : "+WindowList()\hFW
      Debug "Caption :"+#DQUOTE$+Found$+#DQUOTE$
      Break
    EndIf
  Wend
EndIf

Re: Win API: Add a control to an unowned application

Posted: Mon Jun 17, 2013 9:34 am
by Psychophanta
em_uk wrote:Do you mean find the Window Title?

Code: Select all

Structure FindWindowData
  hFW.l ; variable to store a handle
  sFW.s ; variable to store a Window name
  cFW.s ; variable to store a window class name
EndStructure

Global NewList WindowList.FindWindowData()

Procedure.l EnumWindowsCallBack(hFind, lParam)
  WindowName.s = Space(255)
  WindowClass.s = Space(255)
  If GetWindowText_(hFind, WindowName, 255)
    Result = GetClassName_(hFind, WindowClass, 255)
    AddElement(WindowList())
    WindowList()\hFW = hFind
    WindowList()\sFW = WindowName
    WindowList()\cFW = WindowClass
  EndIf
  
  ProcedureReturn #True
  
EndProcedure

Window$=LCase("Purebasic")

If EnumWindows_(@EnumWindowsCallBack(), 0)
  ResetList(WindowList())
  While NextElement(WindowList())
    Debug("Window: " + WindowList()\sFW)
    If FindString(LCase(WindowList()\sFW), Window$, 1)
      Found$=(WindowList()\sFW)
      Debug "------- Found Our Window ---------"
      Debug "hwd : "+WindowList()\hFW
      Debug "Caption :"+#DQUOTE$+Found$+#DQUOTE$
      Break
    EndIf
  Wend
EndIf
I open 'cmd.exe' and looks like your tip does not find it :(

Re: Win API: Add a control to an unowned application

Posted: Fri Jun 21, 2013 10:09 am
by em_uk
change

Code: Select all

.
.
WindowList()\hFW = hFind
WindowList()\sFW = WindowName  
WindowList()\cFW = WindowClass
Debug WindowName
EndIf

.
.
.
Window$=LCase("cmd.exe")
.
.
It found the console on my machine.

Re: Win API: Add a control to an unowned application

Posted: Fri Jun 21, 2013 11:18 am
by Psychophanta
Thanks a lot, it is useful to me.