Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi CreateWindowEx erfolgreich ?! (https://www.delphipraxis.net/101111-createwindowex-erfolgreich.html)

Neutral General 8. Okt 2007 15:53


CreateWindowEx erfolgreich ?!
 
Hi,

Ich erstelle gerade ein Fenster mit CreateWindowEx:



Delphi-Quellcode:
procedure TNVCLImageEx.RegisterImageControl;
var ImgClass: TWndClassEx;
    m: TMethod;
begin
  m.Code := @TNVCLImageEx.ImgProc;
  m.Data := Self;

  FillChar(ImgClass,SizeOf(TWndClassEx),0);
  ImgClass.cbSize := SizeOf(TWndClassEx);
  ImgClass.hInstance := hInstance;
  ImgClass.style := CS_HREDRAW or CS_VREDRAW;
  ImgClass.lpszClassName := 'IMAGE';
  ImgClass.hbrBackground := GetSysColorBrush(COLOR_BACKGROUND);
  ImgClass.lpfnWndProc := MakeProcInstance(m);
  RegisterClassEx(ImgClass);
end;

constructor TNVCLImageEx.Create(AParent: TNVCLControl);
begin
  inherited Create(AParent);
  RegisterImageControl;
  FHeight := 300;
  FWidth := 300;
  FHandle := CreateWindowEx(0,'IMAGE',nil,WS_CHILD or WS_VISIBLE,0,0,
                            FWidth,FHeight,AParent.Handle,FID,hInstance,nil);
end;
Also ich bin mir nicht sicher ob das ganze jetzt erstellt wird aber FHandle ist 0. Und ich hab grad keine Ahnung was das Problem ist. ImgProc wird übrigens aufgerufen.

Delphi-Quellcode:
function TNVCLImageEx.ImgProc(wnd: HWND; uMsg: UINT; wp: WPARAM;
  lp: LPARAM): LResult;
begin
  if FHandle = 0 then
   FHandle := wnd; // wnd = gültig
Dort setzte ich das Handle nochmal nachträglich. Innerhalb der procedure ist FHandle dann auch gültig aber danach is es wieder 0 -.-

Gruß
Neutral General

Apollonius 8. Okt 2007 15:57

Re: CreateWindowEx erfolgreich ?!
 
Du willst sicher MakeObjectInstance und nicht MakeProcInstance verwenden. MakeProcInstance ist eine veraltete WinAPI-Funktion.

Neutral General 8. Okt 2007 16:01

Re: CreateWindowEx erfolgreich ?!
 
Hi,

Diese Methode hab ich von Luckie um Methodenpointer in normale procedurepointer umzuwandeln.

Delphi-Quellcode:
function TNVCLForm.MakeProcInstance(M: TMethod): Pointer;
begin
  // Ausführbaren Speicher alloziieren fü 15 Byte an Code
  Result := VirtualAlloc(nil, 15, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  asm
    // MOV ECX,
    MOV BYTE PTR [EAX], $B9
    MOV ECX, M.Data
    MOV DWORD PTR [EAX+$1], ECX
    // POP EDX (bisherige Rücksprungadresse nach edx)
    MOV BYTE PTR [EAX+$5], $5A
    // PUSH ECX (self als Parameter 0 anfügen)
    MOV BYTE PTR [EAX+$6], $51
    // PUSH EDX (Rücksprungadresse zurück auf den Stack)
    MOV BYTE PTR [EAX+$7], $52
    // MOV ECX, (Adresse nach ecx laden)
    MOV BYTE PTR [EAX+$8], $B9
    MOV ECX, M.Code
    MOV DWORD PTR [EAX+$9], ECX
    // JMP ECX (Sprung an den ersten abgelegten Befehl und Methode aufrufen)
    MOV BYTE PTR [EAX+$D], $FF
    MOV BYTE PTR [EAX+$E], $E1
    // hier kein Call, ansonsten würde noch eine Rücksprungadresse auf den Stack gelegt
  end;
end;
Das ist jetzt die von meiner TNVCLForm.. Da klappt das ganze auch. Ich habe auch gemerkt das es vielleicht doch irgendwie dadran liegt weil ich auch keine WM_CREATE Message bekomme..

Gruß
Neutral General

Apollonius 8. Okt 2007 16:05

Re: CreateWindowEx erfolgreich ?!
 
Hast du mal den Rückgabewert von RegisterClassEx geprüft? Außerdem wäre eine Auswertung von GetLastError hilfreich.

Neutral General 8. Okt 2007 16:09

Re: CreateWindowEx erfolgreich ?!
 
Nach RegisterClassEx sagt er : "Das System kann die angegebene Datei nicht finden". :roll:

Apollonius 8. Okt 2007 16:24

Re: CreateWindowEx erfolgreich ?!
 
Mir ist gerade was grundsätzliches an deinem Code aufgefallen. Zuersteinmal sollte MakeProcInstance wohl ein Klassenmethode sein, aber das ist nicht so wichtig. Wichtiger ist, dass für jede neue Instanz nochmal versucht wird, die Fensterklasse zu registrieren. Das kann nicht gutgehen. Am besten solltest du ein globale Variable einführen, die den Zustand, ob bereits registriert wurde, speichert.

Eine Lösung für dein Problem habe ich allerdings nicht. Versuche doch mal, einen etwas eindeutigeren Namen für die Klasse zu verwenden.

Neutral General 8. Okt 2007 16:28

Re: CreateWindowEx erfolgreich ?!
 
Also ich erstelle dieses Objekt im Moment sowieso nur ein einziges mal von daher dürfte das nichts ausmachen. MakeProcInstance ist eine Methode von TNVCLImageEx. Hab nur die von der Form gepostet.

Den Namen der Klasse ('IMAGE') hab ich auch schon geändert in alles mögliche...

Gruß
Neutral General

sirius 8. Okt 2007 18:52

Re: CreateWindowEx erfolgreich ?!
 
Hast du beim Testen auch ein Parent-Window?

Neutral General 8. Okt 2007 18:55

Re: CreateWindowEx erfolgreich ?!
 
Ja habe ich. Aber der Hauptfehler ist das scheinbar die Klasse gar nicht registriert wird.

GetLastError sagt nach RegisterClassEx:

Zitat:

---------------------------
Error
---------------------------
The system cannot find the file specified
---------------------------
OK
---------------------------
Wobei ich mich Frage welche Datei da gemeint ist. Das ganze hat doch eigentlich nichts mit Dateien zu tun....

Gruß
Neutral General

sirius 8. Okt 2007 19:06

Re: CreateWindowEx erfolgreich ?!
 
Und ist das Ergebnis von Registerclass 0?


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:09 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz