GetClassInfoA always returns false

Übergeordnete Themen zum gesamten Paket passend
Antworten
satmax
Senior Member
Beiträge: 312
Registriert: 24. September 2015, 10:05
Wohnort: Biberbach, Austria
Kontaktdaten:

GetClassInfoA always returns false

Beitrag von satmax »

Hier ein Beispiel wie GetClassNameA() immer false liefert.

Code: Alles auswählen

WNDCLASSA is Structure
	style is unsigned int  //Type C : UINT
	lpfnWndProc is int //Type C : WNDPROC
	cbClsExtra is int //Type C : int
	cbWndExtra is int //Type C : int
	hInstance is system int //Type C : HINSTANCE
	hIcon is system int //Type C : HICON
	hCursor is system int //Type C : HCURSOR
	hbrBackground is system int //Type C : HBRUSH
	lpszMenuName is system int //Type C : LPCSTR
	lpszClassName is system int //Type C : LPCSTR
END

strWndClass is WNDCLASSA

sErr is string
FunctionReturn is boolean // C type:BOOL
hInstance is system int // C type:HINSTANCE
lpClassName is system int  // C type:LPCSTR, this is the address of a string, you also have the ability to specify a string directly
lpWndClass is int // Pointer on structure WNDCLASSA
sClassName is string on 255  // = "WinDevObject        "
sClassName1 is string on 255
nMaxCount is int = 255 // C type:int
sTitle is string


lpClassName = &sClassName
lpWndClass = &strWndClass

IF LoadDLL("user32.dll") = 0 THEN
	ErrorInfo(errCode)
	ErrorInfo(errMessage)
END

hInstance=Handle()  // Handle vom Main Fenster holen
MyTrace("Handle: ", hInstance)
sTitle=SysWinTitle(hInstance)  // Mit Titel prüfen ob richtiges Handle
MyTrace("Fenstertitel: ", sTitle)

FunctionReturn=API("user32","GetClassNameA", hInstance, lpClassName, nMaxCount)  // OK ClassName ("WinDevObject") wird ausgelesen 

// Ab hier test

sClassName1 = StringRetrieve(lpClassName, srASCIIZAddress)  // OK sClassName "WinDevObject"
sClassName = StringRetrieve(lpClassName, srASCIIZAddress)

// FunctionReturn ist ab hier immer false!
FunctionReturn=CallDLL32("user32","GetClassInfoA",hInstance, lpClassName, lpWndClass)
// FunctionReturn ist immer false!
sErr=ErrorInfo (errSystemCode)   
sErr=ErrorInfo (errSystemMessage)  // Class name not found
 
Hat da noch jemand eine Idee dazu?

Lewi
Member
Beiträge: 74
Registriert: 3. September 2010, 14:45
Wohnort: Hamburg
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von Lewi »

Die API-Funktion "GetClassInfoA" hat die folgenden Aufrufparameter:

Code: Alles auswählen

FunctionReturn is boolean             // C type:BOOL
hInstance is system int               // C type:HINSTANCE
lpClassName is system int            // C type:LPCSTR, this is the address of a string, you also have the ability to specify a string directly
lpWndClass is int                   // Pointer on structureWNDCLASSA

FunctionReturn=API("USER32","GetClassInfoA",hInstance,lpClassName,lpWndClass)
Gruß, Olaf

satmax
Senior Member
Beiträge: 312
Registriert: 24. September 2015, 10:05
Wohnort: Biberbach, Austria
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von satmax »

Ja, rufe ich ja genau so auf, oder?

Code: Alles auswählen

FunctionReturn=CallDLL32("user32","GetClassInfoA",hInstance, lpClassName, lpWndClass)
beziehungsweise:

Code: Alles auswählen

FunctionReturn=API("user32","GetClassInfoA",hInstance, lpClassName, lpWndClass)
Mit hInstance hatte ich einen Fehler (mein Kollege hat mich darauf aufmerksam gemacht). Ich hatte einfach das Fensterhandle genommen.
Jetzt nehme ich für hInstance SysInstance(). Funktioniert aber auch noch nicht so wie es soll. Bemerkenswert ist, das SysInstance() und GetWindowLongA unterschiedliche Handles liefern:

Code: Alles auswählen

// Handle auf die eigene Instanz abfragen( Instance()!!! ist nicht das korrekte Handle )
hInstance= SysInstance()
MyTrace("Handle: ", hInstance)
hi is system int =API("USER32","GetWindowLongA",hHandle,(-6))  // #define GWL_HINSTANCE       (-6)
MyTrace("Handle: ", hi)
ergibt im Trace():
24.11.2016 09:24:39.24: <Handle: ><4194304><><><><><><><><>
24.11.2016 09:24:40.83: <Handle: ><621150208><><><><><><><><>

IMHO sollte das dass gleiche Handle sein. Ein Programm hat ja nur eine Instanz, oder?

Herbert
Site Admin
Beiträge: 529
Registriert: 23. Februar 2010, 08:06
Wohnort: Langenthal, Schweiz
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von Herbert »

Kann ich als Laie hier wissen, was die Mission dieses Themas ist, also was ist der Grund dieses Codes? Ev. gibt's andere Ansätze...

satmax
Senior Member
Beiträge: 312
Registriert: 24. September 2015, 10:05
Wohnort: Biberbach, Austria
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von satmax »

Gerne, ich versuche es :)

Jedes WIndowsprogramm verfügt über einen WndClassName. Alle Windev Programme erhalten automatisch den Classname "WindevObject". Ich brauche aber in meinem Programm einen anderen WndClassName, so wie "4711-12345678-8765432" Es gibt andere, fertige Programme die setrzen das so voraus und senden an das Programm mit diesem WinClassName verschiedene Windows Nachrichten.

Herbert
Site Admin
Beiträge: 529
Registriert: 23. Februar 2010, 08:06
Wohnort: Langenthal, Schweiz
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von Herbert »

Danke, aha.

Du definierst
sClassName is string on 255 // = "WinDevObject "
sClassName1 is string on 255

Falls du Unicode als default definiert hast, musst ev. so definieren.... API-Aufrufe verwenden immer ASCIIZ-Strings! Und Pointer verwenden diese.

Code: Alles auswählen

sClassName is ASCIIZ string on 255  // = "WinDevObject        "
sClassName1 is ASCIIZ string on 255
http://doc.windev.com/en-US/?1000003014 ... PI_example

satmax
Senior Member
Beiträge: 312
Registriert: 24. September 2015, 10:05
Wohnort: Biberbach, Austria
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von satmax »

Das habe ich geändert, war es aber auch nicht. Ich verscuhe hier nochmals zu erklären was der aktuelle Status ist:

Code: Alles auswählen

// hi erhält Programm Instance Handle
hi is system int =API("USER32","GetWindowLongA",hHandle,(-6))  // #define GWL_HINSTANCE       (-6)

// strWndCLass auslesen und somit struktur initialisieren
FunctionReturn=API("user32","GetClassInfoA", hi, lpClassName, &strWndClass) //
// sclName enthält <sClassName1: ><0D377BFA-D304-4D02-A15B-50B75506DB74><><><><><><><><>
strWndClass.lpszClassName = &sclname
FunctionReturn=API("USER32","RegisterClassA", &strWndClass)  // Liefert true

lpClassName = &sclname
FunctionReturn=API("user32","GetClassInfoA",hi, lpClassName, &strWndClass)
sClassName1 = StringRetrieve(strWndClass.lpszClassName, srASCIIZAddress)
MyTrace("sClassName1: ", sClassName1)  // Hier kommt der richtige, mein gewünschter Classname heraus: 0D377BFA-D304-4D02-A15B-50B75506DB74

lpClass1 is system int  // C type:LPCSTR, this is the address of a string, you also have the ability to specify a string directly
sClass1 is ASCIIZ string on 255 = WND_CLASSNAME_WATCHDOG // ""  // = "WinDevObject        "
lpClass1 = &sClass1
FunctionReturn=API("user32","GetClassNameA", hHandle, lpClass1, nMaxCount)  /
sClass1 = StringRetrieve(lpClass1, srASCIIZAddress)  // Hier kommt der falsche CLass Name WinDevObject
MyTrace("sClass1: ", sClass1) 
Kontrolliere ich nun das laufende Programm mit einem externen Tool (WinLister) steht immer noch WinDEvObject drinen. :huh: Ergo muss ich annehmen das falsche Handle zu haben.
Dateianhänge
24-11-_2016_19-31-16.jpg
24-11-_2016_19-31-16.jpg (38.73 KiB) 17562 mal betrachtet

Herbert
Site Admin
Beiträge: 529
Registriert: 23. Februar 2010, 08:06
Wohnort: Langenthal, Schweiz
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von Herbert »

Hmmm.

ist hhandle definiert?
hHandle is system int

hhandle zugewiesen?
ist hHandle=Handle()
hier ist zu beachten, dass du unbedingt das erste Startfenster der App nimmst. Handle ohne Argument nimmt das aktuelle Fenster.
Eventuell hast du bereits ein zweites Fenster geöffnet und nimmst nicht das Startwindow der Applikation?

wahrscheinlich hast alles so...
In den Foren finde ich nichts dazu...

Eventuell stellst mal dort eine passende Frage dazu? http://forum.pcsoft.fr/en-US/index.awp

satmax
Senior Member
Beiträge: 312
Registriert: 24. September 2015, 10:05
Wohnort: Biberbach, Austria
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von satmax »

Ja, es gibt nur ein Fenster: WIN_MAIN

Neues Projekt anlegen, WIN_MAIN Fesnter erstellen, und folgender Code in End of initialization of WIN_Main kopieren:

Habe alle mögliche herumexperimentiert:

Code: Alles auswählen

WNDCLASSA is Structure   //40 
	style is unsigned int  //Type C : UINT
	lpfnWndProc is int //Type C : WNDPROC
	cbClsExtra is int //Type C : int
	cbWndExtra is int //Type C : int
	hInstance is system int //Type C : HINSTANCE
	hIcon is system int //Type C : HICON
	hCursor is system int //Type C : HCURSOR
	hbrBackground is system int //Type C : HBRUSH
	lpszMenuName is system int //Type C : LPCSTR
	lpszClassName is system int //Type C : LPCSTR
END
  
strWndClass is WNDCLASSA
MyTrace("Dim: ", Dimension(strWndClass))

sErr is string
FunctionReturn is boolean // C type:BOOL
hAppInstance is system int // C type:HINSTANCE
hWinMain is system int   // 
hAppInstanceAPI is system int 
lpClassName is system int  // C type:LPCSTR, this is the address of a string, you also have the ability to specify a string directly
lpWndClass is system int // Pointer on structure WNDCLASSA
sClassName is ASCIIZ string on 254  // = "WinDevObject        "
sClassName1 is ASCIIZ string on 254
nMaxCount is int = 254 // C type:int
sTitle is string
sName is string=ExeInfo(exeName) 
//hi= SysInstance(sName)  

lpClassName = &sClassName
lpWndClass = &strWndClass

IF LoadDLL("user32.dll") = 0 THEN
	ErrorInfo(errCode)
	ErrorInfo(errMessage)
END

// hAppInstance= Instance()
hWinMain=Handle()  // Handle vom Main Fenster holen
hAppInstance= SysInstance(sName)
hAppInstanceAPI = API("USER32","GetWindowLongA",hWinMain,(-6))  // #define GWL_HINSTANCE       (-6)

MyTrace("Handle: ", hAppInstance)
sTitle=SysWinTitle(hWinMain)  // Mit Titel prüfen ob richtiges Handle
MyTrace("Fenstertitel: ", sTitle)


// hWinMain: A handle to the window and, indirectly, the class to which the window belongs.
// lpClassName: The class name string.
FunctionReturn=API("user32","GetClassNameA", hWinMain, lpClassName, nMaxCount)  // OK ClassName wird ausgelesen 
MyTrace("FunctionReturn GetClassNameA: ", FunctionReturn)
sClassName = StringRetrieve(lpClassName, srASCIIZAddress)

// GetClassNameA liefern beide false:
//FunctionReturn=API("user32","GetClassNameA", hAppInstance, lpClassName, nMaxCount)  // OK ClassName wird ausgelesen 
//MyTrace("FunctionReturn GetClassNameA: ", FunctionReturn)
//sClassName = StringRetrieve(lpClassName, srASCIIZAddress)
//
//hAppInstanceAPI = API("USER32","GetWindowLongA",hWinMain,(-6))  // #define GWL_HINSTANCE       (-6)
//FunctionReturn=API("user32","GetClassNameA", hAppInstanceAPI, lpClassName, nMaxCount)  // OK ClassName wird ausgelesen 
//MyTrace("FunctionReturn GetClassNameA: ", FunctionReturn)
//sClassName = StringRetrieve(lpClassName, srASCIIZAddress)
//


// Watchdog GUID
sclName is ASCIIZ string on 255 = WND_CLASSNAME_WATCHDOG

// Handle auf die eigene Instanz abfragen( Instance()!!! ist nicht das korrekte Handle )

MyTrace("Handle: ", hAppInstanceAPI, sName)


//hAppInstanceAPI [in, optional]
//Type: HINSTANCE
//A handle to the instance of the application that created the class. To retrieve information about classes defined by the system (such as buttons or list boxes), set this parameter to NULL.
FunctionReturn=API("user32","GetClassInfoA", hAppInstanceAPI, lpClassName, &strWndClass)
MyTrace("FunctionReturn GetClassInfoA: ", FunctionReturn)
//// GetClassInfoA liefern bei de false
//FunctionReturn=API("user32","GetClassInfoA", hAppInstance, lpClassName, &strWndClass)
//MyTrace("FunctionReturn GetClassInfoA: ", FunctionReturn)
//FunctionReturn=API("user32","GetClassInfoA", hWinMain, lpClassName, &strWndClass)
//MyTrace("FunctionReturn GetClassInfoA: ", FunctionReturn)

sclName = WND_CLASSNAME_WATCHDOG
strWndClass.lpszClassName = &sclName
strWndClass.hInstance = hAppInstanceAPI
FunctionReturn=API("USER32","RegisterClassA", &strWndClass)
MyTrace("FunctionReturn RegisterClassA: ", FunctionReturn)

strWndClass.hInstance = hAppInstance
FunctionReturn=API("USER32","RegisterClassA", &strWndClass)
MyTrace("FunctionReturn RegisterClassA: ", FunctionReturn)

strWndClass.hInstance = hWinMain
FunctionReturn=API("USER32","RegisterClassA", &strWndClass)
MyTrace("FunctionReturn RegisterClassA: ", FunctionReturn)

strWndClass.hInstance = hAppInstanceAPI
lpClassName = &sclName
FunctionReturn=API("user32","GetClassInfoA",hAppInstanceAPI, lpClassName, &strWndClass)
MyTrace("FunctionReturn GetClassInfoA: ", FunctionReturn)
sClassName1 = StringRetrieve(strWndClass.lpszClassName, srASCIIZAddress)
MyTrace("sClassName1: ", sClassName1)

FunctionReturn=API("user32","GetClassInfoA",hAppInstanceAPI, lpClassName, &strWndClass)
MyTrace("FunctionReturn GetClassInfoA: ", FunctionReturn)
sClassName1 = StringRetrieve(strWndClass.lpszClassName, srASCIIZAddress)
MyTrace("sClassName1: ", sClassName1)



lpClass1 is system int  // C type:LPCSTR, this is the address of a string, you also have the ability to specify a string directly
sClass1 is ASCIIZ string on 255 = WND_CLASSNAME_WATCHDOG // ""  // = "WinDevObject        "
lpClass1 = &sClass1
FunctionReturn=API("user32","GetClassNameA", hWinMain, lpClass1, nMaxCount)  
sErr=ErrorInfo (errSystemCode)
sErr=ErrorInfo (errSystemMessage)

MyTrace("FunctionReturn GetClassNameA: ", FunctionReturn)

sClass1 = StringRetrieve(lpClass1, srASCIIZAddress)

MyTrace("sClass1: ", sClass1) 


// Ab hier test

GetClassName is API Description
GetClassName..DLLName = "user32"
GetClassName..FunctionName = "GetClassNameA"
GetClassName..ReturnType = apiBoolean
GetClassName..Parameter[1]..Type = apiSystemInt
GetClassName..Parameter[2]..Type = apiBuffer
GetClassName..Parameter[3]..Type = apiSystemInt
sClassName=""
FunctionReturn = GetClassName(hWinMain,lpClassName,nMaxCount)

sClassName=""

// FunctionReturn=API("user32","GetClassNameA", hHandle, lpClass1, nMaxCount)  
FunctionReturn=API("user32","GetClassNameA", hWinMain, lpClassName, nMaxCount)  
sClass1 = StringRetrieve(lpClassName, srASCIIZAddress)

sErr=ErrorInfo (errSystemCode)
sErr=ErrorInfo (errSystemMessage)

sClassName1 = StringRetrieve(lpClassName, srASCIIZAddress)
sClassName = StringRetrieve(lpClassName, srASCIIZAddress)
Was ich absolut nicht verstehe ist warum

Code: Alles auswählen

sName is string=ExeInfo(exeName)
hAppInstance= SysInstance(sName)
ein anderes Handle wie

Code: Alles auswählen

hAppInstanceAPI = API("USER32","GetWindowLongA",hWinMain,(-6))  // #define GWL_HINSTANCE       (-6)
liefert.

Herbert
Site Admin
Beiträge: 529
Registriert: 23. Februar 2010, 08:06
Wohnort: Langenthal, Schweiz
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von Herbert »

Was ist, wenn du es in den global declarations machst? So stellst du um, bevor alle anderen Elemente initialisieert werden.

satmax
Senior Member
Beiträge: 312
Registriert: 24. September 2015, 10:05
Wohnort: Biberbach, Austria
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von satmax »

Global declaration kommt aber vor End of initialization...

Herbert
Site Admin
Beiträge: 529
Registriert: 23. Februar 2010, 08:06
Wohnort: Langenthal, Schweiz
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von Herbert »

Ja, aber die Instanzen und der Handle bestehen doch bereits.

satmax
Senior Member
Beiträge: 312
Registriert: 24. September 2015, 10:05
Wohnort: Biberbach, Austria
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von satmax »

Ja, habe ich auch versucht, ohne Erfolg.

Was ich absolut nicht verstehen kann ist, warum gibt es 2 verschiedene APP - Handles:

Code: Alles auswählen

hAppInstance= SysInstance()
ist ein anderes Handle wie

Code: Alles auswählen

hAppInstanceAPI = API("USER32","GetWindowLongA",hWinMain,(-6))  // #define GWL_HINSTANCE       (-6)
Ein registireren der Klasse mit dem Handle hAppInstanceAPI funktioniert ja. Nur ist diese Klasse dann nur innerhalb von meinem Windev Programm sichtbar, nicht von Windows. Auf das Handle hAppInstance funktioniert die Registrierung nicht.

Gibt es da eventuell noch eine andere Möglichkeit an das "echte" Programmhandle zu kommen?

satmax
Senior Member
Beiträge: 312
Registriert: 24. September 2015, 10:05
Wohnort: Biberbach, Austria
Kontaktdaten:

Re: GetClassInfoA always returns false

Beitrag von satmax »

Ich habe dieses Problem inzwischen gelöst. Ich lege mir via Windows API einfach ein "hidden" Window an. Da kann ich die Klasse registrieren und meine eigene Message Queue verwalten. Klappt wunderbar. Bei Interesse kann ich gerne die Details zur Verfügung stellen.

Antworten