2012-04-04 13 views
11

Tengo una especie de pregunta abstracta sobre el uso directo de Win32 para la programación de GUI. Como mi única experiencia previa con la GUI ha sido en Java utilizando Swing, estoy acostumbrado a tener un administrador de diseño que automáticamente redimensiona/reposiciona botones y cosas cuando se cambia el tamaño de una ventana. ¿Hay algo similar que viene incorporado en la API de Win32, o uno tiene que recalcular manualmente los tamaños y las posiciones utilizando ubicaciones absolutas en cada repintado? Supongo que esta es, de hecho, la manera de hacerlo, porque no he encontrado nada que se parezca a la administración del diseño en los documentos de MSDN, pero como esos (en mi opinión) son un poco laberínticos, es posible que no los haya visto.Diseño en el programa GUI de Win32

Gracias por su ayuda!

+0

que tienen algo de código para MFC que podría adaptarse a las llamadas de la API de Win32: http://stackoverflow.com/a/5739620/5987 –

Respuesta

1

Es posible que tenga que mirar en MFC que es un envoltorio alrededor de win32 que ocultará la mayor parte de la parte difícil en el diseño de la GUI. Le proporcionará un editor de recursos donde puede crear y ubicar sus controles en un formato como WYSIWYG.

+1

yo no era consciente del MFC incluye un controlador de disposición de control de alto nivel. Pensé que realmente no ayuda con los controles de reposicionamiento después de un cambio de tamaño. –

+0

Posicionamiento! = Diseño – Mehrdad

4

No. La API Win32 no incluye código para cambiar el tamaño y cambiar la posición de los controles. Tienes que escribir el tuyo o usar una biblioteca. Microsoft ofrece un editor de recursos en Visual Studio y MFC (un contenedor de C++ alrededor de la API), pero ninguno de ellos aborda su problema real (cambiar el tamaño y reposicionar automáticamente). He usado wxWidgets, que es mucho más coherente que MFC (en mi opinión) y tiene un concepto llamado "sizers" que se ocupa de cambiar el tamaño y la reposición.

+0

¡Gracias por aclarar! –

4

Debe echar un vistazo a ATL (incluido con Visual C++) y, en consecuencia, WTL (no enviado, debe descargarse).

Compilan casi por completo a "Win32 directo", mientras que proporcionan un buen envoltorio de C++ a su alrededor. Son muy ligeros (casi no peso, en realidad, es Win32 directo para el 99% de las llamadas), y sin embargo, WTL está diseñado para imitar las características de MFC, por lo que sigue siendo bastante útil.

Sin embargo, debe ser semi-bueno con C++.

La forma más sencilla es utilizar CDialogResize<CYourDialog> en algo así como

// Put ATL includes before here.. 
#include <atlcrack.h> // Include this from WTL for message map 
#include <atlframe.h> // Include this from WTL for CDialogResize 

class CYourDialog : CDialogImpl<CYourDialog>, CDialogResize<CYourDialog> 
{ 
    BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam) 
    { 
     this->DlgResize_Init();      // Initialize the positions 
    } 

    BEGIN_MSG_MAP_EX(CYourDialog) // Learn about message maps if you haven't 
     MSG_WM_INITDIALOG(OnInitDialog) 
     CHAIN_MSG_MAP(CDialogResize<CYourDialog>) // Chain to the parent 
    END_MSG_MAP() 

    BEGIN_DLGRESIZE_MAP(CYourDialog) 
     DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_Y)  // Layout for "OK" button 
    END_DLGRESIZE_MAP() 
}; 

DLGRESIZE_CONTROL() es el corazón de la disposición - DLSZ_MOVE_Y, por ejemplo, dice que desea mover verticalmente IDOK. También puedes agruparlos, pero se vuelve complicado (a veces tampoco entiendo lo que está pasando) ... pero una vez que lo haces bien, en realidad no es tan malo. :)


Aquí es un auto-contenida ejemplo:

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 

#include <atlbase.h> 
extern CComModule _Module; 
#include <atlapp.h> 
#include <atlcrack.h> 
#include <atlwin.h> 
#include <atlframe.h> 
#include "resource.h" 

class CMyDialog : public CDialogImpl<CMyDialog>, CDialogResize<CMyDialog> 
{ 
public: 
    enum { IDD = IDD_DIALOG1 }; 

private: 
    BOOL OnInitDialog(CWindow wndFocus, LPARAM) 
    { 
     this->DlgResize_Init(); 
     return TRUE; 
    } 

    void OnOK(UINT, int, HWND) { this->EndDialog(ERROR_SUCCESS); } 
    void OnCancel(UINT, int, HWND) { this->EndDialog(ERROR_CANCELLED); } 

    BEGIN_MSG_MAP_EX(CMyDialog) 
     MSG_WM_INITDIALOG(OnInitDialog) 
     COMMAND_HANDLER_EX(IDOK, BN_CLICKED, OnOK) 
     COMMAND_HANDLER_EX(IDCANCEL, BN_CLICKED, OnCancel) 
     CHAIN_MSG_MAP(CDialogResize<CMyDialog>) 
    END_MSG_MAP() 

    BEGIN_DLGRESIZE_MAP(CMyDialog) 
     DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_X | DLSZ_MOVE_Y) 
     DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y) 
    END_DLGRESIZE_MAP() 
}; 

CComModule _Module; 

int WINAPI _tWinMain(
    HINSTANCE hInstance, HINSTANCE hInstPrevious, 
    LPTSTR lpCmdLine, int nCmdShow) 
{ 
    _Module.Init(NULL, hInstance); 
    { 
     CMyDialog dialog; 
     dialog.DoModal(); 
    } 
    _Module.Term(); 
} 

compilarlo, también necesita un archivo llamado resource.h con el siguiente contenido en la misma carpeta del proyecto:

#define IDD_DIALOG1      101 
#define IDR_RT_MANIFEST1    103 

Y un archivo llamado Sample.rc agregado al proyecto, que se puede editar con Visual Studio y que contiene el diseño del diálogo:

#include "resource.h" 

#define APSTUDIO_READONLY_SYMBOLS 
#include "afxres.h" 
#undef APSTUDIO_READONLY_SYMBOLS 
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 
#ifdef _WIN32 
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 
#pragma code_page(1252) 
#endif 
#ifdef APSTUDIO_INVOKED 
1 TEXTINCLUDE 
BEGIN 
    "resource.h\0" 
END 

2 TEXTINCLUDE 
BEGIN 
    "#include ""afxres.h""\r\n" 
    "\0" 
END 

3 TEXTINCLUDE 
BEGIN 
    "\r\n" 
    "\0" 
END 
#endif 
IDD_DIALOG1 DIALOGEX 0, 0, 316, 180 
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME 
EXSTYLE WS_EX_APPWINDOW 
CAPTION "Dialog" 
FONT 8, "MS Shell Dlg", 400, 0, 0x1 
BEGIN 
    DEFPUSHBUTTON "OK",IDOK,205,159,50,14 
    PUSHBUTTON  "Cancel",IDCANCEL,259,159,50,14 
END 
#ifdef APSTUDIO_INVOKED 
GUIDELINES DESIGNINFO 
BEGIN 
    IDD_DIALOG1, DIALOG 
    BEGIN 
     LEFTMARGIN, 7 
     RIGHTMARGIN, 309 
     TOPMARGIN, 7 
     BOTTOMMARGIN, 173 
    END 
END 
#endif 
#endif 
#ifndef APSTUDIO_INVOKED 
#endif 
+1

@NathanMcCrina: ATL es literalmente solo una interfaz/envoltorio C++ para Win32; si estás usando C++, te estarías haciendo pasar un mal rato si usas las API de estilo C, agrega * nada * y te hace seguir las malas prácticas (por ejemplo, muchas variables globales, que son una mala idea, pero un error fácil). En cuanto a DirectX: estoy bastante seguro de que encajarían bien, no es diferente de Win32, después de todo, ya que es lo mismo. Sería un ejemplo completo para la ayuda de ATL (probablemente no DirectX, ¿cómo mostrar un diálogo)? Puedo hacer un diálogo y mostrarte cómo, realmente no es tan difícil. – Mehrdad

+0

Claro, no voy a decir no a los ejemplos! –

+0

@NathanMcCrina: Ver actualización. – Mehrdad

3

Here y here puedes encontrar un par de buenos ejemplos probados sobre cómo hacerlo. No hay necesidad de reinventar la rueda.

Cuestiones relacionadas