Hola:
He creado un formulario con Windows Form (Win32). Quiero añadir en él dos botones. Por ahora he hecho esto.
Paso 1:
(https://social.msdn.microsoft.com/Forums/getfile/1249949)
Paso 2:
(https://social.msdn.microsoft.com/Forums/getfile/1249950)
Pado 3:
(https://social.msdn.microsoft.com/Forums/getfile/1249951)
Se me genera códigos pero no se ve el formulario. Lo que demuestra se un engorro programar así hoy en día, pero hay empresas que si programan así y enseñan en algunas universidades les gusten a los alumnos o no.
Paso 4:
(https://social.msdn.microsoft.com/Forums/getfile/1249955)
Aquí lo dejo el formulario como si fuese por defeto 300x300 pero en realidad es muy grande para mi gusto.
Quiero hacer dos cosas. Poner el tamaño del formulario a 300 x 300 y introducir 2 botones. Quiero hacer.
Un botón se llama: Abrir y el otro Cerrar.
¿Cómo se hace?
Saludos.
PD: La verdad, no sabía que fuera tan coñazo, pesado, complicado en hacer lo que estoy pidiendo.
Revisa el post, no se ve nada.
Vuelve a cargar la página para que se vean las imágenes, son 4, cada paso una captura.
Si no se ve nada por mucho que hagas, me avisas y lo subo en otro lado.
Bueno, ocurre que los links de Microsoft a veces pasan primero por una web de selección de cuenta Microsoft, por lo que no e veía la imagen.
Por lo demás, probablemente te interesa más buscar un proyecto de ejemplo con lo que dices. Los controles con WinApi son bastante diferentes a con C# y otros frameworks.
https://msdn.microsoft.com/en-us/library/windows/desktop/hh298354%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 (https://msdn.microsoft.com/en-us/library/windows/desktop/hh298354%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396)
Buenas:
Me alegro que ya se pueda ver als capturas de pantalla.
En todo el proyecto he encontrado el código para redimensionar la ventana aquí.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
Pisiste el enlace, pero no se parece nada para modificar las coordenadas X, Y, así pongo los valores a 300 x 300.
Dios mio, si que es complicado el santo formulario con el Win32. ;)
En el ejemplo que diste:
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
100, // Button width
100, // Button height
m_hwnd, // Parent window
NULL, // No menu.
(HINSTANCE)GetWindowLong(m_hwnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
Es todo un reto.
Saludos.
Cita de: Meta en 7 Abril 2018, 18:46 PMDios mio, si que es complicado el santo formulario con el Win32. ;)
Es todo un reto.
Si querés algo equivalente en C/C++ de C# o VB.NET tendrías que crear el proyecto con la opción de CLR que se vé en la primera imagen...
B#
CLR es .net. Estoy haciendo pruebas con Win32, C++ nativo. ;)
Cita de: Meta en 7 Abril 2018, 18:46 PM
Buenas:
Me alegro que ya se pueda ver als capturas de pantalla.
En todo el proyecto he encontrado el código para redimensionar la ventana aquí.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
Pisiste el enlace, pero no se parece nada para modificar las coordenadas X, Y, así pongo los valores a 300 x 300.
Dios mio, si que es complicado el santo formulario con el Win32. ;)
En el ejemplo que diste:
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
100, // Button width
100, // Button height
m_hwnd, // Parent window
NULL, // No menu.
(HINSTANCE)GetWindowLong(m_hwnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
Es todo un reto.
Saludos.
Más que complicado, es un workflow diferente, además de no orientado a objetos. Fíjate en la función CreateWindow y sus parámetros en MSDN, son muchos parámetros porque son muchas opciones, pero nada más.
Buenas:
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
100, // Button width
100, // Button height
m_hwnd, // Parent window
NULL, // No menu.
(HINSTANCE)GetWindowLong(m_hwnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
HWND hWnd = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
Ahora mismo averiguando poner el formulario al tamaño de 300 x 300 que no logro ni para atrás.
HWND hWnd = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
...tienes que usar la función SetWindowPos()
https://msdn.microsoft.com/es-es/library/a1yzfz6d.aspx
Buenas:
No se ni donde poner ese código.
aaaa.cpp:
// aaaa.cpp: define el punto de entrada de la aplicación.
//
#include "stdafx.h"
#include "aaaa.h"
#define MAX_LOADSTRING 100
// Variables globales:
HINSTANCE hInst; // Instancia actual
WCHAR szTitle[MAX_LOADSTRING]; // Texto de la barra de título
WCHAR szWindowClass[MAX_LOADSTRING]; // nombre de clase de la ventana principal
// Declaraciones de funciones adelantadas incluidas en este módulo de código:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: colocar código aquí.
// Inicializar cadenas globales
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_AAAA, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Realizar la inicialización de la aplicación:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_AAAA));
MSG msg;
// Bucle principal de mensajes:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCIÓN: MyRegisterClass()
//
// PROPÓSITO: registrar la clase de ventana.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_AAAA));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_AAAA);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// FUNCIÓN: InitInstance(HINSTANCE, int)
//
// PROPÓSITO: guardar el identificador de instancia y crear la ventana principal
//
// COMENTARIOS:
//
// En esta función, se guarda el identificador de instancia en una variable común y
// se crea y muestra la ventana principal del programa.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
// ######################################################################
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
100, // Button width
100, // Button height
m_hwnd, // Parent window
NULL, // No menu.
(HINSTANCE)GetWindowLong(m_hwnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
// ######################################################################
//
// FUNCIÓN: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PROPÓSITO: procesar mensajes de la ventana principal.
//
// WM_COMMAND - procesar el menú de aplicaciones
// WM_PAINT - Pintar la ventana principal
// WM_DESTROY - publicar un mensaje de salida y volver
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Analizar las selecciones de menú:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Agregar cualquier código de dibujo que use hDC aquí...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Controlador de mensajes del cuadro Acerca de.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Hay dos códigos más, el del botón:
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"OK", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
100, // Button width
100, // Button height
m_hwnd, // Parent window
NULL, // No menu.
(HINSTANCE)GetWindowLong(m_hwnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
Que lo dice aquí (https://msdn.microsoft.com/es-es/library/windows/desktop/hh298354(v=vs.85).aspx?f=255&MSPPError=-2147217396), y el punto de coordenada que lo dice aquí (https://msdn.microsoft.com/es-es/library/a1yzfz6d.aspx) como han puesto.
Coordenada.
void CMyApp::OnHideApplication()
{
//m_pMainWnd is the main application window, a member of CMyApp
ASSERT_VALID(m_pMainWnd);
// hide the application's windows before closing all the documents
m_pMainWnd->ShowWindow(SW_HIDE);
m_pMainWnd->ShowOwnedPopups(FALSE);
// put the window at the bottom of z-order, so it isn't activated
m_pMainWnd->SetWindowPos(&CWnd::wndBottom, 0, 0, 0, 0,
SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
}
Saludos.
Puedes meter la función en la misma función de instancia. Jo que tampoco es nada del otro mundo :
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// AQUI POR EJEMPLO!!! pos : (100,100), size(600,400)
SetWindowPos(hWnd, 0, 100, 100, 600, 400, NULL);
return TRUE;
}
Muchas gracias campeón.
Aún así me dice algo más de un error.
#include "stdafx.h"
#include "aaaa.h"
#define MAX_LOADSTRING 100
// Variables globales:
HINSTANCE hInst; // Instancia actual
WCHAR szTitle[MAX_LOADSTRING]; // Texto de la barra de título
WCHAR szWindowClass[MAX_LOADSTRING]; // nombre de clase de la ventana principal
// Declaraciones de funciones adelantadas incluidas en este módulo de código:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: colocar código aquí.
// Inicializar cadenas globales
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_AAAA, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Realizar la inicialización de la aplicación:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_AAAA));
MSG msg;
// Bucle principal de mensajes:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCIÓN: MyRegisterClass()
//
// PROPÓSITO: registrar la clase de ventana.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_AAAA));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_AAAA);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// FUNCIÓN: InitInstance(HINSTANCE, int)
//
// PROPÓSITO: guardar el identificador de instancia y crear la ventana principal
//
// COMENTARIOS:
//
// En esta función, se guarda el identificador de instancia en una variable común y
// se crea y muestra la ventana principal del programa.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
// ######################################################################
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// AQUI POR EJEMPLO!!! pos : (100,100), size(600,400)
SetWindowPos(hWnd, 0, 100, 100, 600, 400, NULL);
return TRUE;
}
// ######################################################################
//
// FUNCIÓN: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PROPÓSITO: procesar mensajes de la ventana principal.
//
// WM_COMMAND - procesar el menú de aplicaciones
// WM_PAINT - Pintar la ventana principal
// WM_DESTROY - publicar un mensaje de salida y volver
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Analizar las selecciones de menú:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Agregar cualquier código de dibujo que use hDC aquí...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Controlador de mensajes del cuadro Acerca de.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido
Error C2084 la función 'BOOL InitInstance(HINSTANCE,int)' ya tiene un cuerpo aaaa c:\users\usuario\documents\visual studio 2017\projects\aaaa\aaaa\aaaa.cpp 130
A ver Mc fly, no deberías tener dos funciones de instancia :rolleyes:
Buenas:
El como lo hice me funciona pero no aparece botón ni cambio de tamaño del formulario.
// aaaa.cpp: define el punto de entrada de la aplicación.
//
#include "stdafx.h"
#include "aaaa.h"
#define MAX_LOADSTRING 100
// Variables globales:
HINSTANCE hInst; // Instancia actual
WCHAR szTitle[MAX_LOADSTRING]; // Texto de la barra de título
WCHAR szWindowClass[MAX_LOADSTRING]; // nombre de clase de la ventana principal
// Declaraciones de funciones adelantadas incluidas en este módulo de código:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: colocar código aquí.
// Inicializar cadenas globales
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_AAAA, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Realizar la inicialización de la aplicación:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_AAAA));
MSG msg;
// Bucle principal de mensajes:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCIÓN: MyRegisterClass()
//
// PROPÓSITO: registrar la clase de ventana.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_AAAA));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_AAAA);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// FUNCIÓN: InitInstance(HINSTANCE, int)
//
// PROPÓSITO: guardar el identificador de instancia y crear la ventana principal
//
// COMENTARIOS:
//
// En esta función, se guarda el identificador de instancia en una variable común y
// se crea y muestra la ventana principal del programa.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
// ######################################################################
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd2 = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd2)
{
return FALSE;
}
ShowWindow(hWnd2, nCmdShow);
UpdateWindow(hWnd2);
// AQUI POR EJEMPLO!!! posición(100,100), tamaño(600,400)
SetWindowPos(hWnd2, 0, 100, 100, 600, 400, NULL);
return TRUE;
// ######################################################################
}
//
// FUNCIÓN: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PROPÓSITO: procesar mensajes de la ventana principal.
//
// WM_COMMAND - procesar el menú de aplicaciones
// WM_PAINT - Pintar la ventana principal
// WM_DESTROY - publicar un mensaje de salida y volver
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Analizar las selecciones de menú:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Agregar cualquier código de dibujo que use hDC aquí...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Controlador de mensajes del cuadro Acerca de.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Es algún tipo de broma?
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{ // de verdad esto es serio?
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE; // me estas vacilando o algo asi?
// ######################################################################
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd2 = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd2)
{
return FALSE;
}
ShowWindow(hWnd2, nCmdShow);
UpdateWindow(hWnd2);
// AQUI POR EJEMPLO!!! posición(100,100), tamaño(600,400)
SetWindowPos(hWnd2, 0, 100, 100, 600, 400, NULL);
return TRUE;
// ######################################################################
}
Simplemente te tienes que deshacer de las primeras líneas de la instancia... y si en verdad esto es serio creo que lo primero que deberías hacer es aprender a programar C en la consola y luego pasar a cosas mayores.
Ejecuta pero no hace nada, misma pantalla, el tamaño, aunque lo varíe, no hace nada.
#include "stdafx.h"
#include "aaaa.h"
#define MAX_LOADSTRING 100
// Variables globales:
HINSTANCE hInst; // Instancia actual
WCHAR szTitle[MAX_LOADSTRING]; // Texto de la barra de título
WCHAR szWindowClass[MAX_LOADSTRING]; // nombre de clase de la ventana principal
// Declaraciones de funciones adelantadas incluidas en este módulo de código:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: colocar código aquí.
// Inicializar cadenas globales
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_AAAA, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Realizar la inicialización de la aplicación:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_AAAA));
MSG msg;
// Bucle principal de mensajes:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCIÓN: MyRegisterClass()
//
// PROPÓSITO: registrar la clase de ventana.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_AAAA));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_AAAA);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// FUNCIÓN: InitInstance(HINSTANCE, int)
//
// PROPÓSITO: guardar el identificador de instancia y crear la ventana principal
//
// COMENTARIOS:
//
// En esta función, se guarda el identificador de instancia en una variable común y
// se crea y muestra la ventana principal del programa.
//
// ######################################################################
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{ // de verdad esto es serio?
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE; // me estas vacilando o algo asi?
// ######################################################################
hInst = hInstance; // Almacenar identificador de instancia en una variable global
HWND hWnd2 = CreateWindowW(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd2)
{
return FALSE;
}
ShowWindow(hWnd2, nCmdShow);
UpdateWindow(hWnd2);
// AQUI POR EJEMPLO!!! posición(100,100), tamaño(600,400)
SetWindowPos(hWnd2, 0, 50, 50, 100, 100, NULL);
return TRUE;
// ######################################################################
}
// ######################################################################
//
// FUNCIÓN: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PROPÓSITO: procesar mensajes de la ventana principal.
//
// WM_COMMAND - procesar el menú de aplicaciones
// WM_PAINT - Pintar la ventana principal
// WM_DESTROY - publicar un mensaje de salida y volver
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Analizar las selecciones de menú:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Agregar cualquier código de dibujo que use hDC aquí...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Controlador de mensajes del cuadro Acerca de.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
No se programa copiando y pegando código. Ni el código de srWhiteSkull leíste...
Lo mejor es que intentes otro tipo de proyecto de consola, como dice srWhiteSkull. WinAPI no es complicada, pero hay que saber C para usarla. Y saber C no es copiar y pegar trozos de código de la MSDN. Saber C es saber hacer ese código tú; saberlo leer e interpretar, o por lo menos, esforzarse en entenderlo.
Te podemos hacer el código nosotros con un botón. Pero dime tú que utilidad tendría eso.
Hola:
Leer, leer y leer he leído hasta las cejas.
Quiero redimensionar el formulario a 300 x 300 o al menos por ahí de ese tamaño. En cuanto a los dos botones, lo que quiero hacer, es ponerlo en el formulario. Lo que hace el botón, simplemente es abrir la bandeja del disco o lector y el otro cerrar.
En Win32 modo consola C++ es así.
#include "stdafx.h"
#include "Windows.h"
#include "iostream"
using namespace std;
int main()
{
// Título de la ventana.
SetConsoleTitle(L"Consola C++ Win32 2017");
// Variable.
char entrada[] = "\0"; // Guarda A, a, C, y c tipo string que introduces desde la consola.
while (true)
{
// Muestra en pantalla textos.
cout << "Control bandeja del lector: " << endl << endl;
cout << "A - Abrir bandeja." << endl;
cout << "C - Cerrar bandeja." << endl;
cout << "==========================" << endl;
cin >> entrada; // Aquí introduces letras A, a, C, y c.
cout << "\n" << endl;
// Abrir bandeja.
if ((entrada[0] == 'a') || (entrada[0] == 'A'))
{
cout << "Abriendo..." << endl << endl; // Muestra en pantalla textos.
mciSendString(L"set cdaudio door open", nullptr, 0, nullptr);
cout << "Abierto." << endl << endl; // Muestra en pantalla textos.
}
// Cerrar bandeja.
else if ((entrada[0] == 'c') || (entrada[0] == 'C'))
{
cout << "Cerrando..." << endl << endl; // Muestra en pantalla textos.
mciSendString(L"set cdaudio door closed", nullptr, 0, nullptr);
cout << "Cerrado." << endl << endl; // Muestra en pantalla textos.
}
// Si haz pulsado otro caracter distinto de A, C, a, y c aparece
else
{
cout << "Solo pulsar A o C." << endl << endl; // este mensaje.
}
}
return EXIT_SUCCESS;
}
Consola C++ CLR .net:
#include "stdafx.h"
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Text;
[DllImport("winmm.dll")]
extern Int32 mciSendString(String^ lpstrCommand, StringBuilder^ lpstrReturnString,
int uReturnLength, IntPtr hwndCallback);
static void DoEvents()
{
Console::SetCursorPosition(0, 6);
Console::Write("Abriendo...");
}
static void DoEvents2()
{
Console::SetCursorPosition(0, 6);
Console::Write("Cerrando...");
}
int main(array<System::String ^> ^args)
{
StringBuilder^ rt = gcnew StringBuilder(127);
// Título de la ventana.
Console::Title = "Consola C++ CLR 2017";
// Tamaño ventana consola.
Console::WindowWidth = 29; // X. Ancho.
Console::WindowHeight = 8; // Y. Alto.
// Cursor invisible.
Console::CursorVisible = false;
// Posición del mansaje en la ventana.
Console::SetCursorPosition(0, 0);
Console::WriteLine("Control bandeja del lector : \n\n" +
"A - Abrir bandeja. \n" +
"C - Cerrar bandeja. \n" +
"========================== \n");
ConsoleKey key;
//Console::CursorVisible = false;
do
{
key = Console::ReadKey(true).Key;
String^ mensaje = "";
//Asignamos la tecla presionada por el usuario
switch (key)
{
case ConsoleKey::A:
mensaje = "Abriendo...";
Console::SetCursorPosition(0, 6);
DoEvents();
mciSendString("set CDAudio door open", rt, 127, IntPtr::Zero);
mensaje = "Abierto.";
break;
case ConsoleKey::C:
mensaje = "Cerrando...";
Console::SetCursorPosition(0, 6);
DoEvents2();
mciSendString("set CDAudio door closed", rt, 127, IntPtr::Zero);
mensaje = "Cerrado.";
break;
}
Console::SetCursorPosition(0, 6);
Console::Write(" ");
Console::SetCursorPosition(0, 6);
Console::Write(mensaje);
} while (key != ConsoleKey::Escape);
return 0;
}
Formulario C++ CLR .net: (Sólo pongo una imagen, si quieren el código lo subo).
Lo quiero que salga como abajo en formulario pero en Win32. ;)
(https://www.subeimagenes.com/img/captura-1852378.PNG)
Para dejarlo más claro.
Para abrir bandeja se usa este código.
mciSendString(L"set cdaudio door open", nullptr, 0, nullptr);
Cerrar bandeja.
mciSendString(L"set cdaudio door closed", nullptr, 0, nullptr);
Dejando claro que el Winmm.lib está cargado en el Visual Studio.
Es todo lo que quiero saber, antes que nada, crear botones y redimensionar formulario como quiera.
Saludos.
Edito:
Lo que he hecho.
De este código que viene predeterminado.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
De los 0 le puse 300 ya que quiero 300 x 300 y no funciona.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 300, CW_USEDEFAULT, 300, nullptr, nullptr, hInstance, nullptr);
Tuve que cambiar el orden del CW_USEDEFAULT y 300 como indica abajo y por fin funciona la redimensión.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, nullptr, nullptr, hInstance, nullptr);
Por fin funciona esa parte.
La otra parte de los botones no.
Si has leído y no has revisado el código y ves normal que una función retorne impidiendo que parte del código repetido no se ejecute, donde se incluye la función de redimensionar y posicionar, entonces no hay mucho que hacer... a lo mejor en otra vida puede que te des cuenta :xD
Editado, volver a leer el post anterior donde pone Edito:.
Falta este donde encajarlo bien.
HWND btnOK = CreateWindowW(
L"BUTTON", // clase del control
L"OK",
WS_CHILD | WS_PUSBUTTON | WS_VISIBLE, // estilo del control. La clase button puede ser checkbox, radio, etc.
5, 5, // posición respecto del client area del parent
40, 20, // dimensiones del control
hWnd, // --> este es el handle de tu ventana principal
1, // este es el identificador de tu control. De modo predefinido 1 = IDOK, 2 = IDCANCEL
hInstance,
nullptr);
Vale, ahí lo puedes hacer también, pero con la función que te cité te sirve para cualquier componente, incluso ventanas y puedes usarla en cualquier parte del programa, por ejemplo en un evento, ya que la programación en Win32 es así, a base de eventos o mensajes.
https://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows
Buenas:
Por fin.
(https://www.subeimagenes.com/img/captura2-1852537.PNG)
case WM_CREATE:
{
HWND btnOK = CreateWindowW(
L"BUTTON", // Clase del control.
L"Abrir", // Etiqueta del botón.
WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, // Estilo del control. La clase button puede ser checkbox, radio, etc.
45, 135, // Posición respecto del client area del parent.
75, 23, // Dimensiones del control.
hWnd, // --> Este es el handle de la ventana principal.
(HMENU)101, // Este es el identificador del control. De modo predefinido 1 = IDOK, 2 = IDCANCEL
hInst,
nullptr);
HWND btnOK2 = CreateWindowW(
L"BUTTON", // Clase del control.
L"Cerrar", // Etiqueta del botón.
WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, // Estilo del control. La clase button puede ser checkbox, radio, etc.
165, 135, // Posición respecto del client area del parent.
75, 23, // Dimensiones del control.
hWnd, // --> Este es el handle de la ventana principal.
(HMENU)102, // Este es el identificador del control. De modo predefinido 1 = IDOK, 2 = IDCANCEL
hInst,
nullptr);
}
Me falta detallitos como centrar el formulario en el centro de la pantalla.
Ahora voy a por los comandos para abrir y cerrar la bandeja del lector.
Abrir:
mciSendString("set CDAudio door open", rt, 127, IntPtr::Zero);
Cerrar:
mciSendString("set CDAudio door closed", rt, 127, IntPtr::Zero);
Para que funcione, antes hacer esto:
(https://www.subeimagenes.com/img/captura3-1852539.PNG)
(https://www.subeimagenes.com/img/captura4-1852541.PNG)
En el lenguaje C++ del CLR, este es su código.
private: System::Void button_Abrir_Click(System::Object^ sender, System::EventArgs^ e) {
label_Mensaje->Text = "Abriendo...";
Application::DoEvents();
mciSendString("set CDAudio door open", rt, 127, IntPtr::Zero);
label_Mensaje->Text = "Abierto.";
}
Para que funcione bien los eventos del Abriendo... y Abierto.
Sigo investigando.
Saludos y muchas gracias por todo a tod@s.
Buenas de nuevo:
Teniendo el código completo que ya y por fin puse un label y dos botones gracias a estos enlaces y ayudas de ustedes.
https://msdn.microsoft.com/es-es/library/windows/desktop/ms632679(v=vs.85).aspx
https://msdn.microsoft.com/es-es/library/windows/desktop/bb775951(v=vs.85).aspx
(https://www.subeimagenes.com/img/captura-1853213.PNG)
Código commpleto.
#include "stdafx.h"
#include "Bandeja_Form_Win32_cpp.h"
#include "mmsystem.h" // No olvidar.
#define MAX_LOADSTRING 100
// Variables globales:
HINSTANCE hInst; // Instancia actual
WCHAR szTitle[MAX_LOADSTRING]; // Texto de la barra de título
WCHAR szWindowClass[MAX_LOADSTRING]; // nombre de clase de la ventana principal
// Declaraciones de funciones adelantadas incluidas en este módulo de código:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: colocar código aquí.
// Inicializar cadenas globales
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_BANDEJAFORMWIN32CPP, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Realizar la inicialización de la aplicación:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_BANDEJAFORMWIN32CPP));
MSG msg;
// Bucle principal de mensajes:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCIÓN: MyRegisterClass()
//
// PROPÓSITO: registrar la clase de ventana.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_BANDEJAFORMWIN32CPP));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_BANDEJAFORMWIN32CPP);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// FUNCIÓN: InitInstance(HINSTANCE, int)
//
// PROPÓSITO: guardar el identificador de instancia y crear la ventana principal
//
// COMENTARIOS:
//
// En esta función, se guarda el identificador de instancia en una variable común y
// se crea y muestra la ventana principal del programa.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Almacenar identificador de instancia en una variable global
// #######################################################################
// Redimensionar formulario a 300 x 300.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, nullptr, nullptr, hInstance, nullptr);
// #######################################################################
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCIÓN: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PROPÓSITO: procesar mensajes de la ventana principal.
//
// WM_COMMAND - procesar el menú de aplicaciones
// WM_PAINT - Pintar la ventana principal
// WM_DESTROY - publicar un mensaje de salida y volver
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// #######################################################################
// Crear botones Abrir y Cerrar.
case WM_CREATE:
{
HWND btnOK = CreateWindowW(
L"BUTTON", // Clase del control.
L"Abrir", // Etiqueta del botón.
WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, // Estilo del control. La clase button puede ser checkbox, radio, etc.
45, 135, // Posición respecto del client area del parent.
75, 23, // Dimensiones del control.
hWnd, // --> Este es el handle de la ventana principal.
(HMENU)101, // Este es el identificador del control. De modo predefinido 1 = IDOK, 2 = IDCANCEL
hInst,
nullptr);
HWND btnOK2 = CreateWindowW(
L"BUTTON", // Clase del control.
L"Cerrar", // Etiqueta del botón.
WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, // Estilo del control. La clase button puede ser checkbox, radio, etc.
165, 135, // Posición respecto del client area del parent.
75, 23, // Dimensiones del control.
hWnd, // --> Este es el handle de la ventana principal.
(HMENU)102, // Este es el identificador del control. De modo predefinido 1 = IDOK, 2 = IDCANCEL
hInst,
nullptr);
// Label o etiqueta.
HWND edit = CreateWindowW(
L"STATIC", // Clase del control.
L"Hola.", // Etiqueta del botón.
WS_CHILD | SS_SIMPLE | WS_VISIBLE, // Estilo del control. La clase button puede ser checkbox, radio, etc.
125, 55, // Posición respecto del client area del parent.
75, 23, // Dimensiones del control.
hWnd, // --> Este es el handle de la ventana principal.
(HMENU)103, // Este es el identificador del control. De modo predefinido 1 = IDOK, 2 = IDCANCEL
hInst,
nullptr);
}
break;
// #######################################################################
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Analizar las selecciones de menú:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Agregar cualquier código de dibujo que use hDC aquí...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Controlador de mensajes del cuadro Acerca de.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Ahora mismo, debo introducir comandos a los botones y no tengo idea como hacerlo.
En el botón Abrir:
mciSendString("set CDAudio door open", rt, 127, IntPtr::Zero);
En el botón Cerrar:
mciSendString("set CDAudio door closed", rt, 127, IntPtr::Zero);
Si todo marcha bien, habremos acabado.
Gracias.
He puesto este código. Lee los mensajes si o si de forma muy correcta. Probé este código de abajo para abrir la bandeja y da error al compilar.
// #################################################################### Begin.
case IDC_BUTTON_1:
// MessageBox(hWnd, L"Botón 1 pulsado", L"Ejemplo", MB_OK | MB_ICONINFORMATION);
// Mostrar mensaje.
SetWindowText(GetDlgItem(hWnd, IDC_STATIC_1), L"Abriendo... ");
// Abrir bandeja del lector.
mciSendString("set CDAudio door open", nullptr, 0, nullptr);
// Mostrar mensaje Abierto. Que es cuando ya finalizó.
SetWindowText(GetDlgItem(hWnd, IDC_STATIC_1), L"Abierto. ");
break;
case IDC_BUTTON_2:
// Mostrar mensaje.
SetWindowText(GetDlgItem(hWnd, IDC_STATIC_1), L"Cerrando... ");
// Cerrar bandeja del lector.
// mciSendString("set CDAudio closed open", nullptr, 0, nullptr);
// Mostrar mensaje.
SetWindowText(GetDlgItem(hWnd, IDC_STATIC_1), L"Cerrado. ");
break;
// #################################################################### End.
Errores:
Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido
Error (activo) E0167 un argumento de tipo "const char *" no es compatible con un parámetro de tipo "LPCWSTR" Bandeja_Form_Win32_cpp c:\Users\usuario\Documents\Visual Studio 2017\Projects\Bandeja_Form_Win32_cpp\Bandeja_Form_Win32_cpp\Bandeja_Form_Win32_cpp.cpp 201
Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido
Error C2664 'MCIERROR mciSendStringW(LPCWSTR,LPWSTR,UINT,HWND)': el argumento 1 no puede convertirse de 'const char [22]' a 'LPCWSTR' Bandeja_Form_Win32_cpp c:\users\usuario\documents\visual studio 2017\projects\bandeja_form_win32_cpp\bandeja_form_win32_cpp\bandeja_form_win32_cpp.cpp 201
Buenas:
Ya funciona al 100 %. Solo falta pulir algunas cosas como iniciar el formulario en el centro de la pantalla y cambiar el tamaño del texto de la etiqueta STATIC.
Dejo el código completo aquí por si alguien lo necesita o solo le pica la curiosidad.
#include "stdafx.h"
#include "Bandeja_Form_Win32_cpp.h"
#include "mmsystem.h" // No olvidar.
#define MAX_LOADSTRING 100
#define IDC_BUTTON_1 201 // No olvidar.
#define IDC_BUTTON_2 202 // No olvidar.
#define IDC_STATIC_1 303 // No olvidar.
// Variables globales:
HINSTANCE hInst; // Instancia actual
WCHAR szTitle[MAX_LOADSTRING]; // Texto de la barra de título
WCHAR szWindowClass[MAX_LOADSTRING]; // nombre de clase de la ventana principal
// Declaraciones de funciones adelantadas incluidas en este módulo de código:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: colocar código aquí.
// Inicializar cadenas globales
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_BANDEJAFORMWIN32CPP, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Realizar la inicialización de la aplicación:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_BANDEJAFORMWIN32CPP));
MSG msg;
// Bucle principal de mensajes:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCIÓN: MyRegisterClass()
//
// PROPÓSITO: registrar la clase de ventana.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_BANDEJAFORMWIN32CPP));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_BANDEJAFORMWIN32CPP);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// FUNCIÓN: InitInstance(HINSTANCE, int)
//
// PROPÓSITO: guardar el identificador de instancia y crear la ventana principal
//
// COMENTARIOS:
//
// En esta función, se guarda el identificador de instancia en una variable común y
// se crea y muestra la ventana principal del programa.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Almacenar identificador de instancia en una variable global
// ################################################################### Begin.
// Redimensionar formulario a 300 x 300.
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, nullptr, nullptr, hInstance, nullptr);
// #################################################################### End.
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCIÓN: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PROPÓSITO: procesar mensajes de la ventana principal.
//
// WM_COMMAND - procesar el menú de aplicaciones
// WM_PAINT - Pintar la ventana principal
// WM_DESTROY - publicar un mensaje de salida y volver
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// ################################################################### Begin.
// Crear botones Abrir, Cerrar y mostrar mensajes.
case WM_CREATE:
{
HWND btnOK = CreateWindowW(
L"BUTTON", // Clase del control.
L"Abrir", // Etiqueta del botón.
WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, // Estilo del control. La clase button puede ser checkbox, radio, etc.
45, 135, // Posición respecto del client area del parent.
75, 23, // Dimensiones del control.
hWnd, // --> Este es el handle de la ventana principal.
(HMENU)201, // Este es el identificador del control. De modo predefinido 1 = IDOK, 2 = IDCANCEL
hInst,
nullptr);
HWND btnOK2 = CreateWindowW(
L"BUTTON", // Clase del control.
L"Cerrar", // Etiqueta del botón.
WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, // Estilo del control. La clase button puede ser checkbox, radio, etc.
165, 135, // Posición respecto del client area del parent.
75, 23, // Dimensiones del control.
hWnd, // --> Este es el handle de la ventana principal.
(HMENU)202, // Este es el identificador del control. De modo predefinido 1 = IDOK, 2 = IDCANCEL
hInst,
nullptr);
// Label o etiqueta.
HWND edit = CreateWindowW(
L"STATIC", // Clase del control.
L"Hola.", // Etiqueta del botón.
WS_CHILD | SS_SIMPLE | WS_VISIBLE, // Estilo del control. La clase button puede ser checkbox, radio, etc.
125, 55, // Posición respecto del client area del parent.
75, 23, // Dimensiones del control.
hWnd, // --> Este es el handle de la ventana principal.
(HMENU)303, // Este es el identificador del control. De modo predefinido 1 = IDOK, 2 = IDCANCEL
hInst,
nullptr);
}
break;
// #################################################################### End.
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Analizar las selecciones de menú:
switch (wmId)
{
// #################################################################### Begin.
case IDC_BUTTON_1:
// MessageBox(hWnd, L"Botón 1 pulsado", L"Ejemplo", MB_OK | MB_ICONINFORMATION);
// Mostrar mensaje.
SetWindowText(GetDlgItem(hWnd, IDC_STATIC_1), L"Abriendo... ");
// Abrir bandeja del lector.
mciSendString(L"set CDAudio door open", nullptr, 0, nullptr);
// Mostrar mensaje Abierto. Que es cuando ya finalizó.
SetWindowText(GetDlgItem(hWnd, IDC_STATIC_1), L"Abierto. ");
break;
case IDC_BUTTON_2:
// Mostrar mensaje.
SetWindowText(GetDlgItem(hWnd, IDC_STATIC_1), L"Cerrando... ");
// Cerrar bandeja del lector.
mciSendString(L"set CDAudio door closed", nullptr, 0, nullptr);
// Mostrar mensaje.
SetWindowText(GetDlgItem(hWnd, IDC_STATIC_1), L"Cerrado. ");
break;
// #################################################################### End.
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Agregar cualquier código de dibujo que use hDC aquí...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Controlador de mensajes del cuadro Acerca de.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Saludos camaradas. ;)