[WinAPI] Child-Fenster - Theorie? (evtl. mit Codebeispielen)

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.
 
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:
#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);
	}
}
 
Zuletzt bearbeitet:
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
 
Hier ein kleiner Tip für eine erste Verbesserung
2 WNDCLASS sind nicht nötig

Code:
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);
 
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
 
WNDCLASS ist ein Struct, wo nur die Werte für RegisterClass() eingestellt werden
Bei Aufruf von RegisterClass() nimmt Windows die Werte da raus und ordnet sie dem Fenster zu
Danach wird das Struct nicht mehr gebraucht
Wenn du aber danach noch ein weiteres Fenster registrieren willst, kannst du die Werte im Struct nochmal verwenden, soweit sie noch passen
Du änderst also alles was nicht mehr passt und registrierst das nächste Fenster mit dem geänderten Struct
 
hallo,

ich wollte das auch mal Probieren, aber leider kommt bei mir diese Fehlermeldung beim kompalieren:

[Linker error] undefined reference to `_Z8WeltProcP6HWND__jjl@16'

mein Code:
Code:
#define STRICT
#include <windows.h>
#include "main.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WeltProc(HWND WELT, UINT, WPARAM, LPARAM);

HWND WELT;
const char szAppName[] = "Spiel";     

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                   PSTR szCmdLine, int iCmdShow)
{
   HWND       hWnd;     
   MSG        msg;      
   WNDCLASS   wc;       
   
//Erstellung WndProc
   wc.style         =  CS_HREDRAW | CS_VREDRAW;
   wc.cbClsExtra    =  0;
   wc.cbWndExtra    =  0;
   wc.hInstance     =  hInstance;
   wc.hCursor       =  LoadCursor(NULL,IDC_ARROW);
   wc.hIcon         =  LoadIcon(NULL,IDI_APPLICATION);
   wc.hbrBackground =  (HBRUSH)COLOR_BACKGROUND;
   wc.lpszClassName =  szAppName;
   wc.lpszMenuName  =  NULL;
   RegisterClass(&wc); 
   
   hWnd = CreateWindow(szAppName,
                       "Spiel v0.02",
                       WS_SYSMENU,
                       CW_USEDEFAULT,          /* X-Position auf dem Monitor */
                       CW_USEDEFAULT,          /* Y-Position auf dem Monitor */
                       600,          /* Fensterbreite              */
                       400,          /* Fensterhoehe               */
                       NULL,
                       NULL,
                       hInstance,
                       NULL);
   //Erstellung Buttons
   bNeu       =  CreateWindow("button","Neu",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,20,20,100,30,hWnd,(HMENU)Neu,hInstance,NULL);
   bLaden     =  CreateWindow("button","Laden",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,20,60,100,30,hWnd,(HMENU)Laden,hInstance,NULL);
   bSpeichern =  CreateWindow("button","Speichern",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,20,100,100,30,hWnd,(HMENU)Speichern,hInstance,NULL); 
   bEnde      =  CreateWindow("button","Ende",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,20,140,100,30,hWnd,(HMENU)Ende,hInstance,NULL);

//Erstellung WeltProc                    
   wc.lpfnWndProc   =  WeltProc;
   wc.lpszClassName =  "Welt";
   wc.hbrBackground =  (HBRUSH) CreateSolidBrush (RGB ( 128, 128, 128));
   RegisterClass(&wc);
   
   
   ShowWindow(hWnd, iCmdShow);
   UpdateWindow(hWnd);
   
   while (GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

   switch (message)
   {
      case WM_CREATE:
      {
           WELT      =  CreateWindow("Welt",NULL,WS_CHILD,150,0,450,400,WELT,NULL,(HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),NULL);
      }break;
      case WM_COMMAND:
      {
           switch(wParam)
           {
              case Neu:  ShowWindow(WELT, SW_SHOW);
                 break;
           }
      }break;
      case WM_PAINT:
      {
           PAINTSTRUCT ps;
           HDC hDC;
           
           hDC = BeginPaint(hWnd,&ps);
           {
            MoveToEx(hDC,149,0,NULL); 
            LineTo(hDC,149,400);
            
           }EndPaint(hWnd,&ps);
      }break;
      
      case WM_DESTROY:
      {
         PostQuitMessage(0);
         return 0;
      }
   }
   return DefWindowProc(hWnd, message, wParam, lParam);
}

vielen Dank schon mal für Hinweise
 
also, hab mein Fehler behoben:

musste sie Funktion unten aufrufen

Code:
LRESULT CALLBACK WeltProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch(message)
 {
   case WM_PAINT:
   {
         PAINTSTRUCT  ps;
         HDC          hDC;
         const char  Test[] = "TEST";
         
         hDC = BeginPaint(hWnd, &ps);
         {        
            TextOut(hDC, 10, 50, Test, sizeof(Test) - 1);
         }EndPaint(hWnd,&ps);
   }
 }
}

nur jetzt ist das Problem das sich nichts tut wenn ich auf Neu klicke,

was nu?
 
ok, ich habs alles selbst rausgefunden:
er hat in der WM_CREATE nichts erstellt, warum weis ich nicht

naja egal, bei mir geht es nun auch
 
Wenn ich deinen Code richtig verstehe (bitte korrigiert mich), dann hast du eigentlich ja kein WM_CREATE in deiner 2. Callback Funktion und somit wird er dir das nicht ausführen. Wenn du auf die erste dich beziehst, musst du alles in die eine reinpacken.
 

Neue Beiträge

Zurück