Page 1 of 1

WindowFromPoint_()?

Posted: Wed Aug 18, 2010 7:42 pm
by dongnanyanhai
Hi.
I'v got a problem when using the WindowsAPI "WindowFromPoint_(m)".Why the code below alway returns zero?And how can I use the "WindowFromPoint_()" function?

Code: Select all

m.point
m\x = 100
m\y = 100
Debug WindowFromPoint_(m)

Re: WindowFromPoint_()?

Posted: Wed Aug 18, 2010 7:55 pm
by Trond
It's a long story, but PB does not support passing structures as parameters by value, only by reference. WindowFromPoint_() is one of the rare functions that need a structure by value. We can work around this by pretending the structure is a single quad, since both a quad and a POINT is 8 bytes:

Code: Select all

m.point
m\x = 100
m\y = 100
Debug WindowFromPoint_(PeekQ(@m))

Re: WindowFromPoint_()?

Posted: Wed Aug 18, 2010 8:17 pm
by Arctic Fox
Another workaround which seems to work:

Code: Select all

m.point
m\x = 100
m\y = 100
Debug WindowFromPoint_(m\y << 32 + m\x)

Re: WindowFromPoint_()?

Posted: Wed Aug 18, 2010 9:15 pm
by Trond
And two more for the collectors out there: :lol:

Code: Select all

m.q
PokeL(@m, 100)
PokeL(@m+4, 100)
Debug WindowFromPoint_(m)

Code: Select all

Structure QuadPointUnion
  StructureUnion
    p.POINT
    q.q
  EndStructureUnion
EndStructure

m.QuadPointUnion
m\p\x = 100
m\p\y = 100
Debug WindowFromPoint_(m\q)

Re: WindowFromPoint_()?

Posted: Wed Aug 18, 2010 9:22 pm
by Trond
Oh I just can't stop! I guess I forgot to drink my brake fluid today.

Code: Select all

m.POINT
m\x = 100
m\y = 100
Debug WindowFromPoint_(Val("$"+RSet(Hex(m\y), 8, "0")+RSet(Hex(m\x), 8, "0")))

Re: WindowFromPoint_()?

Posted: Wed Aug 18, 2010 9:27 pm
by Trond
There is simply NO MERCY!

Code: Select all

Import ""
  WindowFromPoint(X.l, Y.l)
EndImport

m.POINT
m\x = 100
m\y = 100
Debug WindowFromPoint(m\x, m\y)

Re: WindowFromPoint_()?

Posted: Thu Aug 19, 2010 12:18 am
by dongnanyanhai
Thank you for all of your replies.
Now I will try to use it in my code!

Re: WindowFromPoint_()?

Posted: Thu Aug 19, 2010 8:41 am
by Fred
Trond wrote:There is simply NO MERCY!

Code: Select all

Import ""
  WindowFromPoint(X.l, Y.l)
EndImport

m.POINT
m\x = 100
m\y = 100
Debug WindowFromPoint(m\x, m\y)
Try that one on x64 ;)

Re: WindowFromPoint_()?

Posted: Fri Aug 20, 2010 1:58 pm
by dongnanyanhai
Trond wrote:It's a long story, but PB does not support passing structures as parameters by value, only by reference. WindowFromPoint_() is one of the rare functions that need a structure by value. We can work around this by pretending the structure is a single quad, since both a quad and a POINT is 8 bytes:

Code: Select all

m.point
m\x = 100
m\y = 100
Debug WindowFromPoint_(PeekQ(@m))
Hi,Trond.

I want to know does(or is?) the WinAPI "Process32First" also need a structure by value?

The code below always return Zero.

Code: Select all

Structure pp
  StructureUnion
    p.Processentry32
  EndStructureUnion
EndStructure 
Global pe.pp
Procedure.s GetWinName(shandle.l)
  oPid.l
  GetWindowThreadProcessId_(shandle,@oPid)
  Pth = CreateToolhelp32Snapshot_(#TH32CS_SNAPALL,oPid)
  bOk = Process32First_(pth,pe\p)
  Debug bOK
  While bOk
    If pe\p\th32processID = opid
      Debug pe\p\szexefile
    EndIf
    bOk = Process32Next_(Pth,@pe)
  Wend
EndProcedure

h = OpenWindow(0,0,0,300,160,"欧耶")
Debug GetwinName(h)

Re: WindowFromPoint_()?

Posted: Fri Aug 20, 2010 2:37 pm
by cas
You forgot one thing:
http://msdn.microsoft.com/en-us/library/ms684834%28VS.85%29.aspx wrote:The calling application must set the dwSize member of PROCESSENTRY32 to the size, in bytes, of the structure.

Code: Select all

Procedure.s GetWinName(shandle.l)
  pe.Processentry32
  pe\dwSize = SizeOf(Processentry32) ; <-------------------HERE
  oPid.l
  GetWindowThreadProcessId_(shandle,@oPid)
  Pth = CreateToolhelp32Snapshot_(#TH32CS_SNAPALL,oPid)
  bOk = Process32First_(pth,pe)
  
  While bOk
    If pe\th32processID = opid
      procname$=Space(#MAX_PATH)
      CopyMemory(@pe\szExeFile,@procname$,#MAX_PATH)
      CloseHandle_(Pth)
      ProcedureReturn procname$
    EndIf
    bOk = Process32Next_(Pth,@pe)
  Wend
EndProcedure

h = OpenWindow(0,0,0,300,160,"??")
Debug GetwinName(h)

Re: WindowFromPoint_()?

Posted: Fri Aug 20, 2010 2:57 pm
by dongnanyanhai
cas wrote:You forgot one thing:
http://msdn.microsoft.com/en-us/library/ms684834%28VS.85%29.aspx wrote:The calling application must set the dwSize member of PROCESSENTRY32 to the size, in bytes, of the structure.

Code: Select all

Procedure.s GetWinName(shandle.l)
  pe.Processentry32
  pe\dwSize = SizeOf(Processentry32) ; <-------------------HERE
  oPid.l
  GetWindowThreadProcessId_(shandle,@oPid)
  Pth = CreateToolhelp32Snapshot_(#TH32CS_SNAPALL,oPid)
  bOk = Process32First_(pth,pe)
  
  While bOk
    If pe\th32processID = opid
      procname$=Space(#MAX_PATH)
      CopyMemory(@pe\szExeFile,@procname$,#MAX_PATH)
      CloseHandle_(Pth)
      ProcedureReturn procname$
    EndIf
    bOk = Process32Next_(Pth,@pe)
  Wend
EndProcedure

h = OpenWindow(0,0,0,300,160,"??")
Debug GetwinName(h)

Yeah, You are right!
Now I set the dwsize and this is my new code!Thank you,cas!

Code: Select all

Global pe.Processentry32
pe\dwsize = SizeOf(Processentry32)
Procedure.s GetWinName(shandle.l)
  oPid.l
  GetWindowThreadProcessId_(shandle,@oPid)
  Pth = CreateToolhelp32Snapshot_(#TH32CS_SNAPALL,0)
  bOk = Process32First_(pth,pe)
  While bOk
    If pe\th32processID = opid
      Debug PeekS(@pe\szexefile, -1, #PB_Ascii)
    EndIf
    bOk = Process32Next_(Pth,pe)
  Wend
EndProcedure

h = OpenWindow(0,0,0,300,160,"欧耶")
Debug GetwinName(h)

Re: WindowFromPoint_()?

Posted: Fri Aug 20, 2010 3:37 pm
by cas
I don't see use of global variable "pe.Processentry32" in your code and you are still having memory leak because there is missing "CloseHandle_(Pth)". :wink:
You can always use this to get exe name of your own application:

Code: Select all

Debug GetFilePart(ProgramFilename())

Re: WindowFromPoint_()?

Posted: Fri Aug 20, 2010 4:56 pm
by dongnanyanhai
cas wrote:I don't see use of global variable "pe.Processentry32" in your code and you are still having memory leak because there is missing "CloseHandle_(Pth)". :wink:
You can always use this to get exe name of your own application:

Code: Select all

Debug GetFilePart(ProgramFilename())
Thank you,cas!
I forget to close the handle used.
I want to get other process's filename so I used the main window's handle to test the procedure-"GetWinName".

I've try to use "PBOSL" - PureBasic OpenSource Libraries,there is a function call "GetProcessName(optional PID)" in the "PBOSL".When using that function ,I always get a error "The following PureLibrary is missing: StringExtension" and can not solve it.Than I had to use the WinAPI to get the process's filename.

Sorry for my English !