Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi 1400 Error beim Erstellen eines Fensters via API (https://www.delphipraxis.net/162123-1400-error-beim-erstellen-eines-fensters-via-api.html)

Medium 8. Aug 2011 10:59

AW: 1400 Error beim Erstellen eines Fensters via API
 
Fundstelle:
Zitat:

Zitat von Mangafreak1995 (Beitrag 1115569)
Delphi-Quellcode:
procedure TSForm.Show();
var msg : TMsg;
begin
  with self.windowClass do // private und vom Typ TWndClass
  begin
    Style:= CS_HREDRAW or CS_VREDRAW;
    lpfnWndProc:= @TSForm.WindowProcedure; // protected und mit stdcall versehen
    cbClsExtra:= 0;
    cbWndExtra:= 0;
    hbrBackground:= COLOR_APPWORKSPACE;
    lpszMenuName:= nil;
    lpszClassName:= 'TestSWindow';
    hInstance := hInstance; // <============================ hier so die Ecke :)
    hIcon := LoadIcon(0, IDI_WINLOGO);
    hCursor := LoadCursor(0, IDC_ARROW);
  end;
  if RegisterClass(self.windowClass) = 0 then
    ShowMessage('Fensterklasse konnte nicht registriert werden ' + IntToStr(GetLastError));
  self.hwnd {private HWND} := CreateWindow('TestSWindow', PChar(self.appName) {public und vom Typ String}, WS_CAPTION or WS_VISIBLE or WS_SYSMENU, (GetSystemMetrics(SM_CXSCREEN) - self.w {private, Integer und im Create auf 400 gesetzt}) div 2, (GetSystemMetrics(SM_CYSCREEN) - self.h{private, Integer und im Create auf 500 gesetzt}) div 2, self.w, self.h, 0, 0, hInstance, nil);
  if self.hwnd = 0 then
    ShowMessage('Fenster konnte nicht erzeugt werden ' + IntToStr(GetLastError));
  // is ja egal ... komm ich nicht mal hin
  ExitCode := msg.wParam;
end;


DeddyH 8. Aug 2011 11:03

AW: 1400 Error beim Erstellen eines Fensters via API
 
Jaja, das "ach so bequeme" with :twisted:

Mangafreak1995 8. Aug 2011 11:14

AW: 1400 Error beim Erstellen eines Fensters via API
 
Zitat:

Zitat von DeddyH (Beitrag 1115622)
Jaja, das "ach so bequeme" with :twisted:

Eyy :(

Ich versuchs mal ohne.

Edit:
Habe es so versucht:
Delphi-Quellcode:
  with self.windowClass do
  begin
    Style:= CS_HREDRAW or CS_VREDRAW;
    lpfnWndProc:= @TSForm.WindowProcedure;
    cbClsExtra:= 0;
    cbWndExtra:= 0;
    hbrBackground:= COLOR_APPWORKSPACE;
    lpszMenuName:= nil;
    lpszClassName:= 'WinAPITestWindow';
    hIcon := LoadIcon(0, IDI_WINLOGO);
    hCursor := LoadCursor(0, IDC_ARROW);
  end;
  self.windowClass.hInstance := SysInit.HInstance;
Aber immer noch 1400. Falls es vielleicht hilft, ich arbeite auf Win 5.1/XP Professional 32 bit.

himitsu 8. Aug 2011 11:18

AW: 1400 Error beim Erstellen eines Fensters via API
 
Mann kann auch den entsprechenden Namespace mit angeben.
HInstance ist doch in der Unit System (glaub ich) deklariert, also
Delphi-Quellcode:
hInstance := System.hInstance
.

[edit]
oder eventuell auch SysInit :stupid:


Eventuell mal self.windowClass über FillChar/ZeroMemory vorher komplett auf 0 sezten?

Ansonsten bleibt noch die Möglichkeit mal über den Debugger die ganzen Werte zu prüfen.

Mangafreak1995 8. Aug 2011 11:23

AW: 1400 Error beim Erstellen eines Fensters via API
 
Zitat:

Zitat von himitsu (Beitrag 1115624)
Man kann auch den entsprechenden Namespace mit angeben.
HInstance ist doch in der Unit System (glaub ich) deklariert, also
Delphi-Quellcode:
hInstance := System.hInstance
.

Schon längts passiert ;) Ich weiß, dass man Namespaces (aka Units) mit angeben kann.

Edit:
Delphi-Quellcode:
ZeroMemory(@self.windowClass.hInstance, SizeOf(Cardinal));
bringt nichts :(

Mangafreak1995 8. Aug 2011 11:52

AW: 1400 Error beim Erstellen eines Fensters via API
 
Laut Debugger ist alles mit einem validen Wert bestückt(hInstance : 4194304). Bei CreateWindow durchläuft der Debugger mehrmals die WndProc mit dem Parametern (hwnd:36, uMsg:0, wParam:1243444, lParam:4268636), (hwnd:129, uMsg:0, wParam:1243412, lParam:4268636) und
(hwnd:130, uMsg:0, wParam:0, lParam:4268636). Danach bekommt self.hwnd von CreateWindow den Wert 0 und der 1400 wird geworfen.

EWeiss 8. Aug 2011 13:44

AW: 1400 Error beim Erstellen eines Fensters via API
 
Es ist definitiv so das du das erstellen des Windows nicht abhängig von deiner Classe machen darfst.
Das wird immer fehlschlagen.
Die WinProc muss Statisch also Global definiert sein darf nicht in der Classe gekapselt werden.

PS:
Vorallem darfst du niemals einen Breakpoint bei WinHandle := CreateWindow(
setzen auch dann wird das erstellen des Windows jedesmal fehlschlagen.

gruss

himitsu 8. Aug 2011 13:56

AW: 1400 Error beim Erstellen eines Fensters via API
 
Zitat:

Zitat von EWeiss (Beitrag 1115640)
Vorallem darfst du niemals einen Breakpoint bei WinHandle := CreateWindow(
setzen auch dann wird das erstellen des Windows jedesmal fehlschlagen.

Dem kann ich so nicht zustimmen, denn ich konnte (also ich sowas das letzte Mal gemacht hatte) überall Halptepunkte hinsetzen oder mit F7 durchsteppen, ohne daß es da nennenswerte Probleme gab. :gruebel:
(damals in Delphi 7 und TDE)

EWeiss 8. Aug 2011 14:04

AW: 1400 Error beim Erstellen eines Fensters via API
 
Zitat:

Zitat von himitsu (Beitrag 1115641)
Zitat:

Zitat von EWeiss (Beitrag 1115640)
Vorallem darfst du niemals einen Breakpoint bei WinHandle := CreateWindow(
setzen auch dann wird das erstellen des Windows jedesmal fehlschlagen.

Dem kann ich so nicht zustimmen, denn ich konnte (also ich sowas das letzte Mal gemacht hatte) überall Halptepunkte hinsetzen oder mit F7 durchsteppen, ohne daß es da nennenswerte Probleme gab. :gruebel:
(damals in Delphi 7 und TDE)

Ungläubiger Thomas ;)
Es ist aber so!

Habe es gerade nach deinem Post nochmalig getestet.
Das setzen eines Breakpoint auf WinHandle := CreateWindow( schlägt immer ohne ausnahme fehl.

Ist auch unabhängig von der Delphi Version Das ist Winapi muss überall laufen egal welche Delphi Version das ist.
Schlägt es in D7 fehl dann auch in allen anderen Versionen wie bei mir d2009

Hier deine Lösung!

Delphi-Quellcode:
program API;

uses
  Windows, Messages, SHFolder, inifiles, SysUtils;

type

  TSForm = class
  private
    run:        Boolean;
    ClassNamen: PAnsiChar;
    windowClass: TWndClass;
    Winhandle:  HWND;
    AppName:    PAnsiChar;
    w, h:       Integer;
    msg:        TMsg;
    procedure finale;
    procedure init;
    procedure ShowError(ErrorText: PChar);
    function getAppData() : String;
    procedure keypress(c : Char);
  protected
    //
  public
    constructor Create();
    procedure Show();
    destructor Close();
  end;

var
  win : TSForm;

procedure TSForm.finale;
begin
  //
end;

function WindowProcedure(Winhandle: HWND; uMsg: UINT; wParam: wParam; lParam: LParam):
  lresult; stdcall;
var
  x, y : integer;
begin
  Result := 0;

  case uMsg of
    WM_CREATE:
      begin
        x := GetSystemMetrics(SM_CXSCREEN);
        y := GetSystemMetrics(SM_CYSCREEN);

        MoveWindow(Winhandle, (x div 2) - (win.w div 2),
          (y div 2) - (win.h div 2),
          win.w, win.h, true);
      end;

    WM_DESTROY:
      begin
         win.run := false;
        win.finale();
        PostQuitMessage(0);
      end;
    WM_KEYDOWN:
      begin
        win.KeyPress(Char(Word(wParam)));
      end;

  else
    Result := DefWindowProc(Winhandle, uMsg, wParam, lParam);
  end;
end;

destructor TSForm.Close;
begin

  UnregisterClass(windowClass.lpszClassName, hInstance);
end;

constructor TSForm.Create;
begin

  w := 640;
  h := 400;
end;

function TSForm.getAppData: String;
var
  path : array[0..MAX_PATH] of char;

begin

  if SUCCEEDED(SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, PChar(path[0]))) then
    result := path
  else
    result := '';
end;

procedure TSForm.init;
begin

  run := true;
end;

procedure TSForm.keypress(c: Char);
begin
  //
end;

procedure TSForm.Show;
begin
  //
end;

procedure TSForm.ShowError(ErrorText: PChar);
begin

  MessageBox(Winhandle, ErrorText, 'Error', MB_ICONERROR);
  Halt;
end;


begin
  win := TSForm.Create();

  win.appName := 'WinAPITestApp';
  win.ClassNamen := 'WinAPITestWindow';
  win.windowClass.hInstance := hInstance;

  with win.windowClass do
  begin
    Style          := CS_HREDRAW or CS_VREDRAW;
    lpfnWndProc    := @WindowProcedure;
    cbClsExtra     := 0;
    cbWndExtra     := 0;
    hbrBackground  := COLOR_APPWORKSPACE;
    lpszMenuName   := nil;
    lpszClassName  := win.ClassNamen;
    hIcon          := LoadIcon(0, IDI_WINLOGO);
    hCursor        := LoadCursor(0, IDC_ARROW);
  end;

  if RegisterClass(win.windowClass) = 0 then
    win.ShowError(PChar('#' + IntToStr(GetLastError) + ' : ' + SysErrorMessage(GetLastError)));

  win.WinHandle := CreateWindow(win.windowClass.lpszClassName, win.AppName, WS_CAPTION or WS_VISIBLE or WS_SYSMENU
    or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SIZEBOX, 400,
    400, win.w, win.h, 0, 0, hInstance, nil);

  if win.WinHandle <> 0 then
  begin
    win.init();

    while win.run do
    begin
      if PeekMessage(win.msg, win.WinHandle, 0, 0, PM_REMOVE) then
      begin
        TranslateMessage(win.msg);
        DispatchMessage(win.msg);
      end;
    end;
  end else
  win.ShowError(PChar('#' + IntToStr(GetLastError) + ' : ' + SysErrorMessage(GetLastError)));

  ExitCode := win.msg.wParam;

  win.Show();
  win.Close();

end.

gruss

Mangafreak1995 8. Aug 2011 14:32

AW: 1400 Error beim Erstellen eines Fensters via API
 
Zitat:

Zitat von EWeiss (Beitrag 1115640)
Es ist definitiv so das du das erstellen des Windows nicht abhängig von deiner Classe machen darfst.
Das wird immer fehlschlagen.
Die WinProc muss Statisch also Global definiert sein darf nicht in der Classe gekapselt sein.

PS:
Vorallem darfst du niemals einen Breakpoint bei WinHandle := CreateWindow(
setzen auch dann wird das erstellen des Windows jedesmal fehlschlagen.

gruss

Niemand hat gesagt, dass ich dort einen Punkt gesetzt habe. Es ist nur die Stelle, wo der Fehler geworfen wird und deswegen habe ich diese Stelle einfach ausführlich beschrieben.

Ich probiere mal die globale WndProc.

Edit : Danke für die Lösung. Ich teste das mal.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:57 Uhr.
Seite 3 von 4     123 4      

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