tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
JA
ANTWORTEN
19
ZUGRIFFE
3686
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    HCWD HCWD ist offline Mitglied Gold
    Registriert seit
    May 2006
    Ort
    Mannheim
    Beiträge
    106
    Hi Community.

    Ich befasse mich seid einer Woche mit WinAPI und habe gleich eine Frage.
    Wenn ich ein Hauptfenster erstellt habe und möchte per Menüklick (bsp. ein Login-) Fenster öffnen, dass jedoch im Arbeitsbereich des Hauptfensters erscheinen soll, wie gehe ich theoretisch vor beim Programmieren?

    Reicht da die CreateWindowEx Funktion oder muss ich das komplette Konstrukt nocheinmal programmieren, nur dass ich bei der Parent angeabe nicht mehr Desktop sondern den hWnd vom Hauptfenster angebe.

    Über Codebeispiele würde ich mich freunen, weil die vorhandenen in diesem Forum sind mir nicht ganz ersichtlich.

    Greetz

    HCWD
     
    That's not a bug, that's a feature!

  2. #2
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    680
    Im Prinzip ist ein Child Fenster ein ganz neues Fenster, sprich du fängst den ganzen Ramsch vom Hauptfenster nochmal von vorne an, nur dass ein paar Teile anderswo stehen

    Zuerst brauchst du die WndProc fürs neue Fenster, als Prototyp direkt unterhalb vom Prototyp des Hauptfensters

    Code :
    1
    
    LRESULT CALLBACK MyChildWindow (HWND, UINT, WPARAM, LPARAM);

    Dann brauchst du ein Handle, also machst du aus

    Code :
    1
    2
    3
    
    // vorher HWND hwnd;
    // nachher
    HWND hwnd, MyChild;

    in der WinMain kommt dann unter RegisterClassEx(); nochmal die ganze Struktur für WNDCLASSEX, inkl einem zweiten RegisterClassEx();, man muss aber nur die Werte nochmal angeben, die im Child Fenster anders sind als im Hauptfenster, meist reicht es icon und name zu ändern

    Code :
    1
    2
    3
    4
    5
    
    wc.hIcon = NULL;
    wc.hIconSm = NULL;
    wc.lpszClassName = "MyChildWindowname";
    wc.lpfnWndProc = MyChildWindow;
    RegisterClassEx (&wc);

    Im Hauptfenster brauchst du dann das Event

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    case WM_CREATE:
    {
    MyChild = CreateWindow(
    "MyChildWindowname",
    NULL, // kein Titel
    WS_CHILD | WS_VISIBLE, // Fenster Style
    0,0,0,0, // Position des Fensters innerhalb des Hauptfenster
    hwnd, // Handle des Hauptfensters
    NULL, // kein HMENU
    hinstance, // HINSTANCE des Hauptfensters
    NULL
    );
    return 0;
    }
    break;

    Immer noch im Hauptfenster ein weiteres Event, falls sich die Grösse des Hauptfensters ändert

    Code :
    1
    2
    3
    4
    5
    6
    
    case WM_SIZE:
    {
    MoveWindow(MyChild, 0,0,0,0, true); // Werte für Position eintragen
    return 0;
    }
    break;

    Und schliesslich brauchst du noch die echte WndProc

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    LRESULT CALLBACK MyChildWindow (HWND MyChild, UINT msg, WPARAM wParam, LPARAM lParam)
    {
     
    switch (msg)
    {
    case WM_PAINT:
    {
    // ....
    // ....
    // ....
    }
    break;
     
    // usw
     
    }
     
    return DefWindowProc (MyChild, msg, wParam, lParam);
     
    }

    Sofern nicht zu viele Tippfehler drin sind, sollte das so funktionieren
     

  3. #3
    HCWD HCWD ist offline Mitglied Gold
    Registriert seit
    May 2006
    Ort
    Mannheim
    Beiträge
    106
    Vielen Dank... werd ich gleich mal probieren... eine Frage von vorne rein:

    wird dann dieses Childfenster im Pixelbereich des ersten Fensters sein oder wird man es am kompletten Bildschirm verschieben können?

    2. Frage:

    wird dann das 1. Fenster anwählbar sein? Also werden die Listeners weiter hinlaufen? Oder wird das Child-Fenster modular angezeigt?
     
    That's not a bug, that's a feature!

  4. #4
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    680
    Ein Child Fenster wird nur innerhalb des Parent Fensters angezeigt, verschiebt man es aus dem Parent hinaus, ist es nicht mehr sichtbar, auch nicht mehr anklickbar, aber sehr wohl noch vorhanden
    Bei Klick ins Childfenster reagiert nur das Child Fenster
    Falls das Child Fenster kleiner ist als das Parent oder so verschoben wird, dass ein Teil des Parent sichtbar ist, wird auf einen Klick dort das Parent Fenster reagieren
     

  5. #5
    HCWD HCWD ist offline Mitglied Gold
    Registriert seit
    May 2006
    Ort
    Mannheim
    Beiträge
    106
    Ahhh.... Danke.... somit werde ich mich jetzt mal an das praktische ran machen mit genügend Vorwissen

    Eine Frage zu der MW_COMAND Zeile:

    was muss ich genau da eintragen? den aufruf des Childs oder nur, dass es angezeigt wird?
    Geändert von HCWD (04.12.07 um 18:17 Uhr)
     
    That's not a bug, that's a feature!

  6. #6
    HCWD HCWD ist offline Mitglied Gold
    Registriert seit
    May 2006
    Ort
    Mannheim
    Beiträge
    106
    Ich bekomm das einfach nicht gebacken. Wenn ich das Programm starte, sieht man es so wie es sein soll.... Jedoch sobald ich auf Login im Menü klicke, bricht das Programm sofort ab. Was ist am Code falsch?

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    
    #include <windows.h>
    #include "resource.h"
     
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK LoginProc(HWND, UINT, WPARAM, LPARAM);
     
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
        HWND hWnd;
        MSG Msg;
        
        WNDCLASS WndClass, wc;
        
        WndClass.style = 0;
        WndClass.cbClsExtra = 0;
        WndClass.cbWndExtra = 0;
        WndClass.lpfnWndProc = WndProc;
        WndClass.hInstance = hInstance;
        WndClass.hbrBackground = (HBRUSH) CreateSolidBrush (RGB ( 128, 128, 128));
        WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
        WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        WndClass.lpszMenuName = MAKEINTRESOURCE(IDMAINMENU);
        WndClass.lpszClassName = "WindowClass";
        
        RegisterClass(&WndClass);
        
        wc.style = 0;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.lpfnWndProc = LoginProc;
        wc.hInstance = hInstance;
        wc.hbrBackground = (HBRUSH) CreateSolidBrush (RGB ( 128, 128, 128));
        wc.hCursor = 0;
        wc.hIcon = 0;
        wc.lpszMenuName = NULL;
        wc.lpszClassName = "Login";
        
        RegisterClass(&wc);
        
        hWnd = CreateWindow("WindowClass","GenixX",
            WS_OVERLAPPEDWINDOW,
            0,0,800,600,NULL,NULL,
            hInstance, NULL);
        
        ShowWindow (hWnd, nCmdShow);
        UpdateWindow (hWnd);
        
        while (GetMessage(&Msg, NULL, 0, 0))
        {
            DispatchMessage(&Msg);
        }
        return (Msg.wParam);
    }
     
    LRESULT CALLBACK WndProc (HWND hWnd, UINT uiMessage, WPARAM wParam,LPARAM lParam)
    {
        char string[255];
        HWND login;
        
        switch(uiMessage)
        {            
        case WM_COMMAND:
              switch(LOWORD(wParam))
                 {
                   case IDM_USER_LOGIN:
                    {
                         login = CreateWindow(  "Login",
                                     NULL,
                                     WS_CHILD | WS_VISIBLE | WS_DLGFRAME,
                                     0,
                                     0,
                                     0,
                                     0,
                                     hWnd,
                                     NULL,
                                     ((LPCREATESTRUCT) lParam)->hInstance,
                                     NULL);
                         return 0;
                    }  
                   break;
                   
                   case IDM_CONN_CONNECT:
                     LoadString(GetModuleHandle(NULL),ID_STRING_CONNECT,string,sizeof(string));
                     MessageBox(hWnd,string,"Connect",MB_ICONINFORMATION);
                   break;
                   
                   case IDM_CONN_DISCONNECT:
                     LoadString(GetModuleHandle(NULL),ID_STRING_DISCONNECT,string,sizeof(string));
                     MessageBox(hWnd,string,"Disconnect",MB_ICONINFORMATION);
                   break;
                   
                   case IDM_HELP_ABOUT:
                     LoadString(GetModuleHandle(NULL),ID_STRING_ABOUT,string,sizeof(string));
                     MessageBox(hWnd,string,"Über",MB_ICONINFORMATION);
                   break;
                   
                   case IDM_FILE_QUIT:
                      DestroyWindow(hWnd);
                   break;
                   }
             break;
             
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
            break;
            
        default: 
            return DefWindowProc (hWnd, uiMessage,
                wParam, lParam);
        }
    }
     
    LRESULT CALLBACK LoginProc (HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
    {
        switch(uiMessage)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
            break;
            
        default: 
            return DefWindowProc (hWnd, uiMessage,
                wParam, lParam);
        }
    }
     
    That's not a bug, that's a feature!

  7. #7
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    680
    Das Child hat keine Grösse, alle Werte im CreateWindow 0 und ein WM_SIZE ist im Hauptfenster nicht vorhanden
    Ausserdem erstellt man ein Fenster unter WM_CREATE
    Wenn es da noch nicht sichtbar sein soll, lässt man WS_VISIBLE im CreateWindow weg und macht später

    Code :
    1
    2
    3
    4
    
    case IDM_USER_LOGIN:
                    {
                       ShowWindow(login, SW_SHOW);
                    }

    Ausserdem muss es heissen

    LRESULT CALLBACK LoginProc (HWND login, UINT uiMessage, WPARAM wParam, LPARAM lParam)

    Und dann gibt es in Child Fenstern kein WM_DESTROY

    Mehr habe ich auf den ersten Blick nicht gesehen
     

  8. #8
    HCWD HCWD ist offline Mitglied Gold
    Registriert seit
    May 2006
    Ort
    Mannheim
    Beiträge
    106
    ok danke für deine Antwort. Jedoch hab ich eine theoretische Frage:

    Heißt das, dass alle Hilfsprogramme (Fenster) beim Beispiel "Microsoft Word" schon erstellt sind, nur durch das Menü ich diese anzeige und wieder verstecke?
     
    That's not a bug, that's a feature!

  9. #9
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    680
    Keine Ahnung was die Experten bei M$ machen
    Natürlich gibt es auch Möglichkeiten Fenster in der runtime zu erstellen und wieder zu löschen, aber das erfordert schon ein paar Fachkenntnisse
    Für Anfänger ist die Methode mit SW_SHOW und SW_HIDE sicher besser geeignet
     

  10. #10
    Hallasas Hallasas ist offline Mitglied Gold
    Registriert seit
    Apr 2007
    Beiträge
    116
    Für "kleinere Dinge" wie zum Beispiel die Abfrage von Benutzernamen und Password benutzte ich Dialoge, welche ich als Resource erstellt habe.

    Gruß
     

  11. #11
    HCWD HCWD ist offline Mitglied Gold
    Registriert seit
    May 2006
    Ort
    Mannheim
    Beiträge
    106
    ok. Das Thema mit den Dialogen, ist für mich noch eine "extra Wurst", weil ich mich bei WinAPI und den ganzen Ressourcengebiet noch nicht so gut orientieren kann.

    Kennt jemand von euch ein gutes Tutorial das nur über WinAPI und dem dazugehörigen Themengebieten handelt? Also nichts über MFC und .NET (darüber hab ich ein Buch mir schon zugelegt).

    Ich frage deswegen über das erstellen von Fenster und Dialogen während dem Runtime, weil ich ein kleines "größeres" Programm erstellen wollte, indem man einen Produktionsprozess im Betrieb verbuchen und nachverfolgen kann. Dies habe ich schon bereits in Java (Swing) vollbracht, aber es sieht immer noch besser aus, wenn es ein eigenständiges Programm als Win32 Applikation ist Daher mein Anlauf in C++ und WinAPI.

    Wäre nett wenn mir hier jemand ne Stütze noch geben könnte.
     
    That's not a bug, that's a feature!

  12. #12
    HCWD HCWD ist offline Mitglied Gold
    Registriert seit
    May 2006
    Ort
    Mannheim
    Beiträge
    106
    Soooooooo.... Habe mein Ziel erreicht Ein Parent Fenster, das durch Klick im Menü ein Child Fenster während dem Runtime erstellt.

    Der Code ist komplett von mir selbst verfasst, also verstoßt das Publizieren gegen keine Autorenrechte.

    Hier für die, die ein ähnliches Problem haben, der Code zum Nachschauen:

    *Der Code ist nicht grad am übersichtlichsten, aber hoffe es hilft dem Einen oder Anderen*

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    
    #include <windows.h>
    #include "resource.h"
     
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK LoginProc(HWND, UINT, WPARAM, LPARAM);
    HWND login;
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
        MSG Msg;
        
        // Für 2 Fenster (Parent und Child) die Struktur
        WNDCLASS WndClass, wc;
        
        WndClass.style = sizeof(WNDCLASS);
        WndClass.cbClsExtra = 0;
        WndClass.cbWndExtra = 0;
        WndClass.lpfnWndProc = WndProc;
        WndClass.hInstance = hInstance;
        WndClass.hbrBackground = (HBRUSH) CreateSolidBrush (RGB ( 128, 128, 128));
        WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
        WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        WndClass.lpszMenuName = MAKEINTRESOURCE(IDMAINMENU);
        WndClass.lpszClassName = "WindowClass";
     
        RegisterClass(&WndClass);
     
        wc.style = sizeof(WNDCLASS);
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.lpfnWndProc = LoginProc;
        wc.hInstance = hInstance;
        wc.hbrBackground = (HBRUSH) CreateSolidBrush (RGB ( 128, 128, 128));
        wc.hCursor = 0;
        wc.hIcon = 0;
        wc.lpszMenuName = NULL;
        wc.lpszClassName = "Login";
        
        RegisterClass(&wc);
        
        // Parent wird erstellt!
        HWND hWnd = CreateWindow("WindowClass","GenixX",
            WS_OVERLAPPEDWINDOW,
            ((GetSystemMetrics(SM_CXSCREEN)/2)-400),
            ((GetSystemMetrics(SM_CYSCREEN)/2)-300),
            800,600,
            NULL,
            NULL,
            hInstance,
            NULL);
        
        ShowWindow (hWnd, nCmdShow);
        UpdateWindow (hWnd);
        
        while (GetMessage(&Msg, NULL, 0, 0))
        {
            DispatchMessage(&Msg);
        }
        return (Msg.wParam);
    }
     
    LRESULT CALLBACK WndProc (HWND hWnd, UINT uiMessage, WPARAM wParam,LPARAM lParam)
    {
        char string[255];
        
        switch(uiMessage)
        {    
        case WM_CREATE:
             {
                return 0;
             }             
             break;
             
        case WM_SIZE:
             {
                     MoveWindow(login, 300,200,200,100, true);
                     return 0;
             }
             break;
                   
        case WM_COMMAND:
              switch(LOWORD(wParam))
                 {
                   case IDM_USER_LOGIN:
                    {
                        login = CreateWindow("Login",
                                     "Login",
                                     WS_CHILDWINDOW | WS_OVERLAPPEDWINDOW,
                                     300,
                                     200,
                                     200,
                                     100,
                                     hWnd,
                                     NULL,
                                     (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE), 
                                     NULL);
                        ShowWindow(login, SW_SHOW);
                    }  
                   break;
                   
                   case IDM_CONN_CONNECT:
                     LoadString(GetModuleHandle(NULL),ID_STRING_CONNECT,string,sizeof(string));
                     MessageBox(hWnd,string,"Connect",MB_ICONINFORMATION);
                   break;
                   
                   case IDM_CONN_DISCONNECT:
                     LoadString(GetModuleHandle(NULL),ID_STRING_DISCONNECT,string,sizeof(string));
                     MessageBox(hWnd,string,"Disconnect",MB_ICONINFORMATION);
                   break;
                   
                   case IDM_HELP_ABOUT:
                     LoadString(GetModuleHandle(NULL),ID_STRING_ABOUT,string,sizeof(string));
                     MessageBox(hWnd,string,"Über",MB_ICONINFORMATION);
                   break;
                   
                   case IDM_FILE_QUIT:
                      DestroyWindow(hWnd);
                   break;
                   }
             break;
             
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
            break;
            
        default: 
            return DefWindowProc (hWnd, uiMessage,
                wParam, lParam);
        }
    }
     
    LRESULT CALLBACK LoginProc (HWND login, UINT uiMessage, WPARAM wParam, LPARAM lParam)
    {
        switch(uiMessage)
        {
            
        default: 
            return DefWindowProc (login, uiMessage,
                wParam, lParam);
        }
    }
    Geändert von HCWD (05.12.07 um 16:12 Uhr)
     
    That's not a bug, that's a feature!

  13. #13
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    680
    Glückwunsch,
    schaut noch etwas holprig aus, aber wenn man den Anfang mal hat geht verbessern meist leicht
    Aller Anfang ist schwer, ich kann mich noch gut erinnern als meine Scripts ähnlich ausgesehen haben
    Das wird schon
     

  14. #14
    Thomasio Thomasio ist offline Mitglied Platin
    Registriert seit
    Aug 2006
    Beiträge
    680
    Hier ein kleiner Tip für eine erste Verbesserung
    2 WNDCLASS sind nicht nötig

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    WNDCLASS wc;
        
        wc.style = sizeof(WNDCLASS);
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.lpfnWndProc = WndProc;
        wc.hInstance = hInstance;
        wc.hbrBackground = (HBRUSH) CreateSolidBrush (RGB ( 128, 128, 128));
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
             wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wc.lpszMenuName = MAKEINTRESOURCE(IDMAINMENU);
        wc.lpszClassName = "WindowClass";
     
        RegisterClass(&wc);
     
        wc.hIcon = 0;
        wc.lpszMenuName = NULL;
        wc.lpszClassName = "Login";
        
        RegisterClass(&wc);
     

  15. #15
    HCWD HCWD ist offline Mitglied Gold
    Registriert seit
    May 2006
    Ort
    Mannheim
    Beiträge
    106
    Dazu hab ich sofort eine Frage

    Wieso wird es einfach abgeändert? Ich meine... Diese Veränderungen werden doch auch aufs Parent sich auswirken oder nicht? Wenn nein, kannst du mich aufklären?

    Greetz
     
    That's not a bug, that's a feature!

Ähnliche Themen

  1. WinAPI: Child-Window erneut öffnen
    Von Michl im Forum C/C++
    Antworten: 8
    Letzter Beitrag: 18.07.10, 10:55
  2. Child-Fenster mit dünnem Rahmen
    Von Jellysheep im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 11
    Letzter Beitrag: 09.02.09, 16:43
  3. Tabelle füllen nach parent/child oder child/child beziehung?
    Von cemiboy im Forum Relationale Datenbanksysteme
    Antworten: 13
    Letzter Beitrag: 16.04.08, 13:36
  4. Child Fenster in einem Fenster suchen
    Von Taktaky im Forum Delphi, Kylix, Pascal
    Antworten: 0
    Letzter Beitrag: 25.09.07, 01:18
  5. WinApi child Sync.probleme
    Von dark80 im Forum C/C++
    Antworten: 6
    Letzter Beitrag: 02.08.06, 14:38