2010-05-22 25 views
8

Veo muchos tutoriales y artículos que me muestran cómo hacer un programa de Windows simple, lo cual es genial, pero ninguno de ellos me muestra cómo hacer múltiples ventanas.Cómo hacer varias ventanas usando Win32 API

código Ahora he de trabajo que crea y dibuja una ventana por capas y puedo blit cosas usando GDI para dibujar lo que quiera en él, se arrastra alrededor, incluso hacerlo transparente, etc.

Pero yo quería una segunda área rectangular que puedo dibujar, arrastrar, etc. En otras palabras, una segunda ventana. Probablemente quiera que sea una ventana secundaria. La pregunta es, ¿cómo lo hago?

Además, si alguien conoce algún recurso bueno (preferiblemente en línea) como artículos o tutoriales para la gestión de ventanas en la API de Windows, por favor comparta.

Respuesta

6

Usted puede golpear CreateWindow() más de una vez si lo desea. El bucle de mensajes en su WinMain pasará eventos a todas las ventanas que WinMain crea. Incluso puede crear dos ventanas superpuestas y establecer la ventana principal del 2º para que sea el manejador de la 1ª si así lo desea.

+0

Lo tengo trabajando, finalmente. Funcionó cuando modifiqué mi rutina que crea ventanas permitiéndole registrar una clase de ventana usando una cadena ClassName diferente. ¿Por qué tendría que hacer una clase de ventana separada para la segunda ventana si la funcionalidad no es la misma? –

+0

@Steven Lu: no estoy seguro. La prueba que ejecuté para verificar dos veces solo registró una clase de ventana y pude abrir CreateWindow dos veces. Por supuesto, esto significa que comparten un WndProc. No tienes datos estáticos dentro del WndProc, ¿o sí? – JustJeff

+0

Todavía estaba usando el mismo proc de ventana, pero tenía que ser una clase de ventana diferente, es decir, tenía que llamar a 'RegisterClassEx' con un' WNDCLASSEX :: lpszClassName' diferente. ¿Esto es normal? –

2

Puede crear tantas ventanas como desee utilizando CreateWindow/CreateWindowEx, con la relación entre ellas como desee (propietario/hijo).

Se puede hacer una ventana de "propiedad" de otro con:

SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR) hwndParent); 

Para convertir una ventana al niño, utilizar SetParent.

Tenga en cuenta que la llamada SetWindowLongPtr con GWLP_HWNDPARENT no se comporta como SetParent (MSDN está equivocado en esto, creo). GWLP_HWNDPARENT no convierte una ventana en "hija", sino en "propiedad".

+0

Crea una relación propietario/propietario pasando el controlador de la ventana del propietario a la llamada 'CreateWindow [Ex]' (parámetro 'hWndParent'). Si el estilo de ventana 'WS_CHILD' no está presente,' hWndParent' será el propietario. Si es así, 'hWndParent' designará la ventana padre, y se establecerá una relación padre/hijo en su lugar. – IInspectable

7

Para crear más de una ventana, repita todos los pasos que hizo cuando creó la primera ventana para crear una segunda ventana. Una buena forma de hacerlo es copiar y pegar todo el código de la primera ventana. Luego busque y reemplace en el que reemplace todos los nombres de la primera ventana con nombres únicos para la segunda ventana. El código en el que hago eso está abajo.

Lo más importante a tener en cuenta es que la clase de Windows para la segunda ventana debe tener un nombre único en el código línea "windowclassforwindow2.lpszClassName =" window class2 ". Si no tiene un nombre único, el el registro de windows fallará.

#include <windows.h> 

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam); 
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2,UINT message,WPARAM wParam,LPARAM lParam); 

bool window1closed=false; 
bool window2closed=false; 

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd) 
{ 
    bool endprogram=false; 

    //create window 1 

    WNDCLASSEX windowclassforwindow1; 
    ZeroMemory(&windowclassforwindow1,sizeof(WNDCLASSEX)); 
    windowclassforwindow1.cbClsExtra=NULL; 
    windowclassforwindow1.cbSize=sizeof(WNDCLASSEX); 
    windowclassforwindow1.cbWndExtra=NULL; 
    windowclassforwindow1.hbrBackground=(HBRUSH)COLOR_WINDOW; 
    windowclassforwindow1.hCursor=LoadCursor(NULL,IDC_ARROW); 
    windowclassforwindow1.hIcon=NULL; 
    windowclassforwindow1.hIconSm=NULL; 
    windowclassforwindow1.hInstance=hInst; 
    windowclassforwindow1.lpfnWndProc=(WNDPROC)windowprocessforwindow1; 
    windowclassforwindow1.lpszClassName=L"windowclass 1"; 
    windowclassforwindow1.lpszMenuName=NULL; 
    windowclassforwindow1.style=CS_HREDRAW|CS_VREDRAW; 

    if(!RegisterClassEx(&windowclassforwindow1)) 
    { 
     int nResult=GetLastError(); 
     MessageBox(NULL, 
      L"Window class creation failed", 
      L"Window Class Failed", 
      MB_ICONERROR); 
    } 

    HWND handleforwindow1=CreateWindowEx(NULL, 
     windowclassforwindow1.lpszClassName, 
      L"Parent Window", 
      WS_OVERLAPPEDWINDOW, 
      200, 
      150, 
      640, 
      480, 
      NULL, 
      NULL, 
      hInst, 
      NULL    /* No Window Creation data */ 
); 

    if(!handleforwindow1) 
    { 
     int nResult=GetLastError(); 

     MessageBox(NULL, 
      L"Window creation failed", 
      L"Window Creation Failed", 
      MB_ICONERROR); 
    } 

    ShowWindow(handleforwindow1,nShowCmd); 

    // create window 2 

    WNDCLASSEX windowclassforwindow2; 
    ZeroMemory(&windowclassforwindow2,sizeof(WNDCLASSEX)); 
    windowclassforwindow2.cbClsExtra=NULL; 
    windowclassforwindow2.cbSize=sizeof(WNDCLASSEX); 
    windowclassforwindow2.cbWndExtra=NULL; 
    windowclassforwindow2.hbrBackground=(HBRUSH)COLOR_WINDOW; 
    windowclassforwindow2.hCursor=LoadCursor(NULL,IDC_ARROW); 
    windowclassforwindow2.hIcon=NULL; 
    windowclassforwindow2.hIconSm=NULL; 
    windowclassforwindow2.hInstance=hInst; 
    windowclassforwindow2.lpfnWndProc=(WNDPROC)windowprocessforwindow2; 
    windowclassforwindow2.lpszClassName=L"window class2"; 
    windowclassforwindow2.lpszMenuName=NULL; 
    windowclassforwindow2.style=CS_HREDRAW|CS_VREDRAW; 

    if(!RegisterClassEx(&windowclassforwindow2)) 
    { 
     int nResult=GetLastError(); 
     MessageBox(NULL, 
      L"Window class creation failed for window 2", 
      L"Window Class Failed", 
      MB_ICONERROR); 
    } 

    HWND handleforwindow2=CreateWindowEx(NULL, 
     windowclassforwindow2.lpszClassName, 
      L"Child Window", 
      WS_OVERLAPPEDWINDOW, 
      200, 
      150, 
      640, 
      480, 
      NULL, 
      NULL, 
      hInst, 
      NULL); 

    if(!handleforwindow2) 
    { 
     int nResult=GetLastError(); 

     MessageBox(NULL, 
      L"Window creation failed", 
      L"Window Creation Failed", 
      MB_ICONERROR); 
    } 

    ShowWindow(handleforwindow2,nShowCmd); 
    SetParent(handleforwindow2,handleforwindow1); 
    MSG msg; 
    ZeroMemory(&msg,sizeof(MSG)); 
    while (endprogram==false) { 
     if (GetMessage(&msg,NULL,0,0)); 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
     if (window1closed==true && window2closed==true) { 
      endprogram=true; 
     } 
    } 
    MessageBox(NULL, 
    L"Both Windows are closed. Program will now close.", 
    L"", 
    MB_ICONINFORMATION); 
    return 0; 
} 

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow,UINT msg,WPARAM wParam,LPARAM lParam) 
{ 
    switch(msg) 
    { 
     case WM_DESTROY: { 
      MessageBox(NULL, 
      L"Window 1 closed", 
      L"Message", 
      MB_ICONINFORMATION); 

      window1closed=true; 
      return 0; 
     } 
     break; 
    } 

    return DefWindowProc(handleforwindow,msg,wParam,lParam); 
} 

LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow,UINT msg,WPARAM wParam,LPARAM lParam) 
{ 
    switch(msg) 
    { 
     case WM_DESTROY: { 
      MessageBox(NULL, 
      L"Window 2 closed", 
      L"Message", 
      MB_ICONINFORMATION); 

      window2closed=true; 
      return 0; 
     } 
     break; 
    } 

    return DefWindowProc(handleforwindow,msg,wParam,lParam); 
} 

un ejemplo que utilizan funciones para crear ventanas.

la creación de cada ventana sin una función se puede hacer el código desordenado, sobre todo si se trata de si las declaraciones más complejo. El código a continuación usa un f por separado unction para crear cada ventana. Las primeras tres ventanas tienen un botón de crear ventana para crear la siguiente ventana.

#include <Windows.h> 

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam); 
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam); 
LRESULT CALLBACK windowprocessforwindow3(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam); 
LRESULT CALLBACK windowprocessforwindow4(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam); 

#define createwindowbuttoninwindow1 101 
#define createwindowbuttoninwindow2 201 
#define createwindowbuttoninwindow3 301 

bool window1open,window2open,window3open,window4open=false; 
bool windowclass1registeredbefore,windowclass2registeredbefore, 
    windowclass3registeredbefore,windowclass4registeredbefore=false; 

enum windowtoopenenumt {none,window2,window3,window4}; 

windowtoopenenumt windowtoopenenum=none; 

void createwindow2(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd); 
void createwindow3(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd); 
void createwindow4(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd); 

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd) 
{ 
    bool endprogram=false; 
    WNDCLASSEX windowclassforwindow2; 
    WNDCLASSEX windowclassforwindow3; 
    WNDCLASSEX windowclassforwindow4; 
    HWND handleforwindow2; 
    HWND handleforwindow3; 
    HWND handleforwindow4; 

    //create window 1 
    MSG msg; 
    WNDCLASSEX windowclassforwindow1; 
    ZeroMemory(&windowclassforwindow1,sizeof(WNDCLASSEX)); 
    windowclassforwindow1.cbClsExtra=NULL; 
    windowclassforwindow1.cbSize=sizeof(WNDCLASSEX); 
    windowclassforwindow1.cbWndExtra=NULL; 
    windowclassforwindow1.hbrBackground=(HBRUSH)COLOR_WINDOW; 
    windowclassforwindow1.hCursor=LoadCursor(NULL,IDC_ARROW); 
    windowclassforwindow1.hIcon=NULL; 
    windowclassforwindow1.hIconSm=NULL; 
    windowclassforwindow1.hInstance=hInst; 
    windowclassforwindow1.lpfnWndProc=(WNDPROC)windowprocessforwindow1; 
    windowclassforwindow1.lpszClassName=L"window class 1"; 
    windowclassforwindow1.lpszMenuName=NULL; 
    windowclassforwindow1.style=CS_HREDRAW|CS_VREDRAW; 

    if(!RegisterClassEx(&windowclassforwindow1)) 
    { 
     int nResult=GetLastError(); 
     MessageBox(NULL, 
      L"Window class creation failed", 
      L"Window Class Failed", 
      MB_ICONERROR); 
    } 

    HWND handleforwindow1=CreateWindowEx(NULL, 
      windowclassforwindow1.lpszClassName, 
      L"Window 1", 
      WS_OVERLAPPEDWINDOW, 
      200, 
      150, 
      640, 
      480, 
      NULL, 
      NULL, 
      hInst, 
      NULL    /* No Window Creation data */ 
); 

    if(!handleforwindow1) 
    { 
     int nResult=GetLastError(); 

     MessageBox(NULL, 
      L"Window creation failed", 
      L"Window Creation Failed", 
      MB_ICONERROR); 
    } 

    ShowWindow(handleforwindow1,nShowCmd); 
    bool endloop=false; 
    while (endloop==false) { 
     if (GetMessage(&msg,NULL,0,0)); 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 

     if (windowtoopenenum !=none) { 
      switch (windowtoopenenum) { 
       case window2: 
        if (window2open==false) {              
         createwindow2(windowclassforwindow2,handleforwindow2,hInst,nShowCmd); 
        } 
        break; 
       case window3: 
        if (window3open==false) {   
         createwindow3(windowclassforwindow3,handleforwindow3,hInst,nShowCmd); 
        } 
        break; 
       case window4:    
        if (window4open==false) {    
         createwindow4(windowclassforwindow4,handleforwindow4,hInst,nShowCmd); 
        } 
        break; 
      } 
     windowtoopenenum=none; 
    } 
    if (window1open==false && window2open==false && window3open==false && window4open==false) 
     endloop=true; 

    } 
    MessageBox(NULL, 
      L"All Windows are closed. Program will now close.", 
      L"Message", 
      MB_ICONINFORMATION); 

} 

void createwindow2(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd) { 
    if (windowclass2registeredbefore==false) { 
    ZeroMemory(&wc,sizeof(WNDCLASSEX)); 
    wc.cbClsExtra=NULL; 
    wc.cbSize=sizeof(WNDCLASSEX); 
    wc.cbWndExtra=NULL; 
    wc.hbrBackground=(HBRUSH)COLOR_WINDOW; 
    wc.hCursor=LoadCursor(NULL,IDC_ARROW); 
    wc.hIcon=NULL; 
    wc.hIconSm=NULL; 
    wc.hInstance=hInst; 
    wc.lpfnWndProc=(WNDPROC)windowprocessforwindow2; 
    wc.lpszClassName=L"wc2"; 
    wc.lpszMenuName=NULL; 
    wc.style=CS_HREDRAW|CS_VREDRAW; 

    if(!RegisterClassEx(&wc)) 
    { 
     int nResult=GetLastError(); 
     MessageBox(NULL, 
      L"Window class creation failed", 
      L"Window Class Failed", 
      MB_ICONERROR); 
    } 
    else 
     windowclass2registeredbefore=true; 
    } 
    hwnd=CreateWindowEx(NULL, 
      wc.lpszClassName, 
      L"Window 2", 
      WS_OVERLAPPEDWINDOW, 
      200, 
      170, 
      640, 
      480, 
      NULL, 
      NULL, 
      hInst, 
      NULL    /* No Window Creation data */ 
); 

    if(!hwnd) 
    { 
     int nResult=GetLastError(); 

     MessageBox(NULL, 
      L"Window creation failed", 
      L"Window Creation Failed", 
      MB_ICONERROR); 
    } 

    ShowWindow(hwnd,nShowCmd); 
} 

void createwindow3(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd) { 
    if (windowclass3registeredbefore==false) { 
    ZeroMemory(&wc,sizeof(WNDCLASSEX)); 
    wc.cbClsExtra=NULL; 
    wc.cbSize=sizeof(WNDCLASSEX); 
    wc.cbWndExtra=NULL; 
    wc.hbrBackground=(HBRUSH)COLOR_WINDOW; 
    wc.hCursor=LoadCursor(NULL,IDC_ARROW); 
    wc.hIcon=NULL; 
    wc.hIconSm=NULL; 
    wc.hInstance=hInst; 
    wc.lpfnWndProc=(WNDPROC)windowprocessforwindow3; 
    wc.lpszClassName=L"window class 3"; 
    wc.lpszMenuName=NULL; 
    wc.style=CS_HREDRAW|CS_VREDRAW; 

    if(!RegisterClassEx(&wc)) 
    { 
     int nResult=GetLastError(); 
     MessageBox(NULL, 
      L"Window class creation failed", 
      L"Window Class Failed", 
      MB_ICONERROR); 
    } 
    else 
     windowclass3registeredbefore=true; 
    } 
    hwnd=CreateWindowEx(NULL, 
      wc.lpszClassName, 
      L"Window 3", 
      WS_OVERLAPPEDWINDOW, 
      200, 
      190, 
      640, 
      480, 
      NULL, 
      NULL, 
      hInst, 
      NULL    /* No Window Creation data */ 
); 

    if(!hwnd) 
    { 
     int nResult=GetLastError(); 

     MessageBox(NULL, 
      L"Window creation failed", 
      L"Window Creation Failed", 
      MB_ICONERROR); 
    } 

    ShowWindow(hwnd,nShowCmd); 
} 

void createwindow4(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd) { 
    if (windowclass4registeredbefore==false) { 
     ZeroMemory(&wc,sizeof(WNDCLASSEX)); 
    wc.cbClsExtra=NULL; 
    wc.cbSize=sizeof(WNDCLASSEX); 
    wc.cbWndExtra=NULL; 
    wc.hbrBackground=(HBRUSH)COLOR_WINDOW; 
    wc.hCursor=LoadCursor(NULL,IDC_ARROW); 
    wc.hIcon=NULL; 
    wc.hIconSm=NULL; 
    wc.hInstance=hInst; 
    wc.lpfnWndProc=(WNDPROC)windowprocessforwindow4; 
    wc.lpszClassName=L"window class 4"; 
    wc.lpszMenuName=NULL; 
    wc.style=CS_HREDRAW|CS_VREDRAW; 

    if(!RegisterClassEx(&wc)) 
    { 
     int nResult=GetLastError(); 
     MessageBox(NULL, 
      L"Window class creation failed", 
      L"Window Class Failed", 
      MB_ICONERROR); 
    } 
    else 
     windowclass4registeredbefore=true; 
    } 
    hwnd=CreateWindowEx(NULL, 
      wc.lpszClassName, 
      L"Window 4", 
      WS_OVERLAPPEDWINDOW, 
      200, 
      210, 
      640, 
      480, 
      NULL, 
      NULL, 
      hInst, 
      NULL    /* No Window Creation data */ 
); 

    if(!hwnd) 
    { 
     int nResult=GetLastError(); 

     MessageBox(NULL, 
      L"Window creation failed", 
      L"Window Creation Failed", 
      MB_ICONERROR); 
    } 

    ShowWindow(hwnd,nShowCmd); 
} 

// windows process functions 

LRESULT CALLBACK windowprocessforwindow1(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { 
    switch(message) { 
     case WM_CREATE: 
       window1open=true; 
       CreateWindowEx(NULL, 
       L"BUTTON", 
       L"Open Window 2", 
       WS_TABSTOP|WS_VISIBLE| 
       WS_CHILD|BS_DEFPUSHBUTTON, 
       50, 
       220, 
       150, 
       24, 
       hwnd, 
       (HMENU)createwindowbuttoninwindow1, 
       GetModuleHandle(NULL), 
       NULL); 
      break; 
      case WM_DESTROY: 
       window1open=false; 
       break; 
     case WM_COMMAND: 
      switch LOWORD(wParam) { 
       case createwindowbuttoninwindow1: 
        windowtoopenenum=window2; 
        break; 
      } 
    } 
    return DefWindowProc(hwnd, message, wParam, lParam); 

} 

LRESULT CALLBACK windowprocessforwindow2(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { 
    switch(message) { 
     case WM_CREATE: 
       window2open=true; 
       CreateWindowEx(NULL, 
       L"BUTTON", 
       L"Open Window 3", 
       WS_TABSTOP|WS_VISIBLE| 
       WS_CHILD|BS_DEFPUSHBUTTON, 
       50, 
       220, 
       150, 
       24, 
       hwnd, 
       (HMENU)createwindowbuttoninwindow2, 
       GetModuleHandle(NULL), 
       NULL); 
      break; 
      case WM_DESTROY: 
       window2open=false; 
       break; 
     case WM_COMMAND: 
      switch LOWORD(wParam) { 
       case createwindowbuttoninwindow2: 
        windowtoopenenum=window3; 
        break; 
      } 
    } 
    return DefWindowProc(hwnd, message, wParam, lParam); 
} 

LRESULT CALLBACK windowprocessforwindow3(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { 
    switch(message) { 
     case WM_CREATE: 
       window3open=true; 
       CreateWindowEx(NULL, 
       L"BUTTON", 
       L"Open Window 4", 
       WS_TABSTOP|WS_VISIBLE| 
       WS_CHILD|BS_DEFPUSHBUTTON, 
       50, 
       220, 
       150, 
       24, 
       hwnd, 
       (HMENU)createwindowbuttoninwindow3, 
       GetModuleHandle(NULL), 
       NULL); 
       break; 
       case WM_DESTROY: 
       window3open=false; 
       break; 
     case WM_COMMAND: 
      switch LOWORD(wParam) { 
       case createwindowbuttoninwindow3: 
        windowtoopenenum=window4; 
        break; 
      } 
    } 
    return DefWindowProc(hwnd, message, wParam, lParam); 
} 

LRESULT CALLBACK windowprocessforwindow4(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { 
    switch(message) { 
     case WM_DESTROY: 
      window4open=false; 
      break; 
    } 
    return DefWindowProc(hwnd, message, wParam, lParam); 
} 

Lo que si cierra y vuelve a abrir una ventana?

Si hace clic en el botón de cerrar y vuelve a abrir la misma ventana, tenga en cuenta lo siguiente. Cuando la ventana se cierra después de cerrar el botón de cierre, se destruirá. Pero destruir una ventana no destruye la clase de Windows. Solo destruye la ventana de la función createwindow. Esto hace que sea necesario para la instrucción if en el programa anterior que solo crea la clase de Windows si es la primera vez que se muestra la ventana.

Algunos lado señala

Se puede crear múltiples ventanas con una sola clase de ventanas. Pero el problema con eso es que tiene una función de proceso de Windows para tratar con más de una ventana. Eso funcionaría bien en este simple ejemplo. Pero cuanto más heterogéneas sean las ventanas, mayor será la necesidad de crear una clase de Windows separada para cada ventana.

También las múltiples funciones de createwindow se podrían haber combinado en una función. Tenga en cuenta que la única diferencia entre ellos era la línea de código wc.lpszClassName. Pero es probable que Windows sea diferente el uno del otro, por lo que no es necesario combinar las funciones en una: es más una preferencia que simplemente no tener código repitiendo cosas.

Lectura adicional

El enlace en la página web con el dominio functionx tiene más detalles sobre los conceptos en el diseño de las ventanas. El enlace es here

La página de inicio en functionx.com tiene buenos recursos de aprendizaje de programación. Especialmente importante es esta página que tiene material de referencia de programación para cosas tales como cambiar la clase de Windows, crear listboxes y otros controles de Windows. También es un buen recurso para el aprendizaje de programación win32 en general. functionx.com programación Win32

functionx.com win32 programming

1

Sé que esto ya ha sido contestada, pero yo estaba escribiendo un programa que abre un número arbitrario de ventanas a través de un bucle.

Aquí está mi versión. Básicamente, reutiliza el mismo generador de clases para construir múltiples ventanas. Puedes crear tantos como quieras. Solo asegúrese de ajustar sus matrices HWND [] y WNDCLASSEX wc [] según corresponda.

Nota 1: Este fragmento de código utiliza una ApplicationInstance global, que se deriva de la función WinMain. En su WinMain, asigne hInstance recibido a ApplicationInstance que, en este ejemplo, se supone que está disponible globalmente. Esta es su instancia de ventana de aplicación principal.

Nota 2: Por supuesto, usted tiene que tener la rutina WinProc ya están pre-escrito, e incluido en algún lugar de otro archivo de cabecera, o justo por encima (no se muestra en este ejemplo.) En este código, se le hace referencia como WinProc , cuando se pasa a PopulateClass (proceso WNDPROC)

Nota 3: SpawnWindow admite banderas "centradas" y "maximizadas". Lo que hacen es autoexplicativo.

Además, el nombre de la clase de ventana se genera automáticamente, por lo que nunca tendrá que preocuparse por darle un nombre, simplemente asígnele un buen nombre base.

int WindowCounter = 0; 
WNDCLASSEX wc[1000]; 
HWND hwnd[1000]; 
char class_name[256]; // for auto class name generation 

void PopulateClass(WNDPROC process) { 
    ZeroMemory(&wc[WindowCounter], sizeof(WNDCLASSEX)); 
    wc[WindowCounter].cbSize = sizeof(WNDCLASSEX); 
    wc[WindowCounter].style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC; 
    wc[WindowCounter].lpfnWndProc = process; 
    wc[WindowCounter].cbClsExtra = 0; 
    wc[WindowCounter].cbWndExtra = 0; 
    wc[WindowCounter].hInstance = ApplicationInstance; 
    wc[WindowCounter].hIcon = LoadIcon(nullptr, IDI_APPLICATION); 
    wc[WindowCounter].hCursor = LoadCursor(nullptr, IDC_ARROW); 
    wc[WindowCounter].hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); 
    wc[WindowCounter].lpszMenuName = nullptr; 
    sprintf(class_name, "WindowClass%d", WindowCounter); 
    wc[WindowCounter].lpszClassName = class_name; 
    wc[WindowCounter].hIconSm = nullptr; 
} 

Ahora, vamos a poner todo junto al proporcionar una función SpawnWindow!

HWND SpawnWindow(int x, 
       int y, 
       int width, 
       int height, 
       bool centered = false, 
       bool maximized = false) { 
    PopulateClass(WinProc); 
    RegisterClassEx(&wc[ WindowCounter ]); 
    int config_style = WS_OVERLAPPEDWINDOW; 
    if (maximized) { width = GetSystemMetrics(SM_CXFULLSCREEN); height =  GetSystemMetrics(SM_CYFULLSCREEN); config_style = WS_OVERLAPPEDWINDOW |  WS_MAXIMIZE; } 
    if (centered) { x = (GetSystemMetrics(SM_CXFULLSCREEN)/2) - (width/ 2); y = (GetSystemMetrics(SM_CYFULLSCREEN)/2) - (height/2); } 
    hwnd[WindowCounter] = CreateWindowEx(NULL, 
     wc[WindowCounter].lpszClassName, 
     config.namever(), 
     WS_OVERLAPPEDWINDOW, 
     x, 
     y, 
     width, 
     height, 
     nullptr, 
     nullptr, 
     ApplicationInstance, 
     nullptr); 
    HWND returnID = hwnd[WindowCounter]; 
    ShowWindow(hwnd[WindowCounter++], SW_SHOW); 
    return returnID; 
} 

Por último, crear tantas ventanas como desee con sólo una sola línea de código cada uno:

void CreateWindows() { 
    HWND PrimaryWindow1 = SpawnWindow(500, 500, 250, 250); 
    HWND PrimaryWindow2 = SpawnWindow(500, 500, 250, 250, true); 
    HWND PrimaryWindow3 = SpawnWindow(500, 500, 250, 250, true, true); 
    HWND PrimaryWindow4 = SpawnWindow(100, 100, 150, 150); 
    HWND PrimaryWindow5 = SpawnWindow(450, 500, 350, 150); 
} 

CreateWindows de llamada() de su WinMain, antes de entrar en bucle principal.

Espero que esto ayude a alguien por ahí.

Cuestiones relacionadas