Anfänger fehler ^^



  • Guten Morgen

    hab vor ein paar stunden mit WinAPI angefangen, bzw. das erstellen von Fenstern.
    Hab zum Test mal ein Main Fenster, mit Menu + einem Button erstellt. Klickt man
    auf den Button wird das Programm beendet.

    Drücke ich jetzt jedoch auf Optionen (in der Menüleiste), so beendet er ebenfalls
    das programm. Wieso?

    Nun, soweit bin ich mal:

    #include <Windows.h>
    #include "resource.h"
    
    #define ID_MYID 0
    
    void Button(HWND *handle,HINSTANCE hInstance);
    void SettWindowClass(HINSTANCE hInstance);
    void MainWindow(HWND *handle, HINSTANCE hInstance);
    
    WNDCLASSEX winClass;
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    
      switch(msg)
      {
    	case WM_CLOSE:
    		DestroyWindow(hwnd);
    		break;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	case WM_COMMAND:
    		switch(LOWORD(wParam)){
    			case ID_DATEI_BEENDEN:
    				PostQuitMessage(0);
    				break;
    			case ID_MYID:
    				PostQuitMessage(0);
    				break;
    		}
    		break;
      default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
      }
    
      return 0;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){
    
      HWND handle=NULL;
      MSG msg;
    
      SettWindowClass(hInstance);
    
      MainWindow(&handle, hInstance);
      Button(&handle, hInstance);
    
      ShowWindow(handle, nShowCmd);
      UpdateWindow(handle);
    
      while(GetMessage(&msg, NULL, 0, 0) > 0)
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
    
    	return 0;
    }
    
    void Button(HWND *handle,HINSTANCE hInstance){
    
    	HWND child;
    
    	child = CreateWindow(
    	  "BUTTON", 
    	  "Beenden", 
    	  WS_VISIBLE|WS_CHILD|WS_BORDER, 
    	  460, 
    	  390, 
    	  100, 
    	  30, 
    	  *handle, 
    	  (HMENU)ID_MYID, 
    	  hInstance, 
    	  0);
    
    }
    
    void SettWindowClass(HINSTANCE hInstance){
    
      winClass.cbSize        = sizeof(WNDCLASSEX);
      winClass.style         = 0;
      winClass.lpfnWndProc   = WndProc;
      winClass.cbClsExtra    = 0;
      winClass.cbWndExtra    = 0;
      winClass.hInstance     = hInstance;
      winClass.hIcon         = LoadIcon(0, IDI_APPLICATION);
      winClass.hIconSm       = LoadIcon(0, IDI_APPLICATION);
      winClass.hCursor       = LoadCursor(0, IDC_ARROW);
      winClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
      winClass.lpszMenuName  = (LPCSTR)IDR_MENU1;
      winClass.lpszClassName = "testWindowClassName";
    
      if (!RegisterClassEx(&winClass)) {
        return;
      }
    
    }
    
    void MainWindow(HWND *handle, HINSTANCE hInstance){
    
       *handle = CreateWindowEx(WS_EX_CLIENTEDGE,
        "testWindowClassName",
        "Test",
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
        0,
        0,
        600,
        500,
        NULL,
        NULL,
        hInstance,
        NULL);
    
    }
    

    Resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Visual C++ generated include file.
    // Used by resource.rc
    //
    #define IDR_MENU1                       101
    #define ID_DATEI_NEU                    40001
    #define ID_DATEI_40002                  40002
    #define ID_DATEI_SPEICHERN              40003
    #define ID_DATEI_BEENDEN                40004
    #define ID_HILFE_CREDITS                40005
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        102
    #define _APS_NEXT_COMMAND_VALUE         40006
    #define _APS_NEXT_CONTROL_VALUE         1001
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    

    Weiteres hab ich versucht ein Child-Fenster zu erstellen, nur Verstehe ich jetzt
    folgende dinge nicht wirklich:

    1. Ist ein Child-fenster nun ein eigenständiges Fenster?
    2. Wenn ja, kann ich es ausserhalb des Main-Fensters ziehn?
    3. Wie erstelle ich jetzt genau so ein ChildFenster? ein code-Beispiel wär nice.

    Danke für die Hilfe.

    Gruß
    ITEDVO



  • itedvo schrieb:

    Drücke ich jetzt jedoch auf Optionen (in der Menüleiste), so beendet er ebenfalls
    das programm. Wieso?

    Guck dir mal die Zeilen 24 bis 31 genauer an.

    itedvo schrieb:

    1. Ist ein Child-fenster nun ein eigenständiges Fenster?

    Jain. Es ist zwar ein eigenständiges Fenster, aber mit Einschränkungen. z.B. sollte das Child sich schließen, wenn das Parent geschlossen wird.

    itedvo schrieb:

    2. Wenn ja, kann ich es ausserhalb des Main-Fensters ziehn?

    Ja, kann man.

    itedvo schrieb:

    3. Wie erstelle ich jetzt genau so ein ChildFenster? ein code-Beispiel wär nice.

    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    LRESULT CALLBACK ChildProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
    ATOM MyRegisterClass(HINSTANCE hInstance, WNDPROC proc, const char *name)
    {
      WNDCLASSEX wc = {0};
      wc.cbSize = sizeof(wc);
      wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
      wc.hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW));
      wc.hInstance = hInstance;
      wc.lpfnWndProc = proc;
      wc.lpszClassName = name;
      wc.style = CS_HREDRAW | CS_VREDRAW;
    
      return RegisterClassEx(&wc);
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
      HWND hwnd, child;
      MSG msg;
      const char *className = "MyWindowClass";
      const char *childClassName = "MyChildWindowClass";
    
      if (!MyRegisterClass(hInstance, WindowProc, className))
        MessageBox(0, "RegisterClassEx() failed.", "", 0), exit(-1);
      if (!MyRegisterClass(hInstance, ChildProc, childClassName))
        MessageBox(0, "RegisterClassEx() failed.", "", 0), exit(-2);
    
      hwnd = CreateWindow(className, "Parent", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 
        CW_USEDEFAULT, 640, 480, 0, 0, hInstance, 0);
      if (!hwnd)
        MessageBox(0, "CreateWindow() failed.", "", 0), exit(-3);
    
      child = CreateWindow(childClassName, "Child", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, hwnd, 0, hInstance, 0);
      if (!child)
        MessageBox(0, "CreateWindow() failed.", "", 0), exit(-4);
    
      ShowWindow(hwnd, nCmdShow);
      UpdateWindow(hwnd);
    
      while(GetMessage(&msg, 0, 0, 0))
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
    
      return msg.wParam;
    }
    
    LRESULT CALLBACK ChildProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
      switch (uMsg)
      {
      case WM_CLOSE:
        {
          MessageBox(0, "Und tschuess ;)", "", 0);
          DestroyWindow(hwnd);
          return 0;
        }
      case WM_DESTROY:
        {
          return 0;
        }
      }
      return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
      switch (uMsg)
      {
      case WM_CLOSE:
        {
          DestroyWindow(hwnd);
          return 0;
        }
      case WM_DESTROY:
        {
          PostQuitMessage(0);
          return 0;
        }
      }
      return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    

  • Mod

    Ein Child Window wird immer geschlossen wenn das Parent schließt.
    Childwindows haben den Stil WS_CHILD und ein Parant Window bim erzeugen mit CreateWindow.

    Wie wäre es wen Du einfach mal die CreateWindow Doku lesen würdest, das steht alles drin.



  • danke erst mal für die antwort, jetzt ist mir einiges klarer... aber:

    switch(LOWORD(wParam)){ 
      case ID_DATEI_BEENDEN: 
        PostQuitMessage(0); 
        break; 
      case ID_MYID: 
        PostQuitMessage(0); 
        break; 
    }
    

    hmmm, soviel ich jetzt aus dem tutorial verstanden hab, wird hier abgefragt ob eine
    Message eines Buttons, menüpunkts gesendet wurde. wenn ja, dann müsse ich darauf
    reagieren.

    Ich reagiere ja nur auf den menüpunkt von: Datei --> Beenden und auf den Button
    Beenden. Wieso dann der Menüpunkt Optionen auch?

    [EDIT] Und wenn ich in diesem Child-fenster wiederum ein Childfenster mache, ist
    im Prinzip das Childfenster das Parentfenster vom neuen Childfenster oder?


Anmelden zum Antworten