Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: Meta en 7 Abril 2018, 17:49 PM

Título: [SOLUCIONADO] ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 7 Abril 2018, 17:49 PM
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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: ivancea96 en 7 Abril 2018, 17:58 PM
Revisa el post, no se ve nada.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 7 Abril 2018, 18:07 PM
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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: ivancea96 en 7 Abril 2018, 18:23 PM
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)
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: 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í.

Código (cpp) [Seleccionar]
   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:
Código (cpp) [Seleccionar]
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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: BloodSharp en 7 Abril 2018, 18:51 PM
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#
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 7 Abril 2018, 19:04 PM
CLR es .net. Estoy haciendo pruebas con Win32, C++ nativo. ;)
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: ivancea96 en 7 Abril 2018, 19:31 PM
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í.

Código (cpp) [Seleccionar]
   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:
Código (cpp) [Seleccionar]
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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 7 Abril 2018, 20:04 PM
Buenas:

Código (cpp) [Seleccionar]
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.


Código (cpp) [Seleccionar]
   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.

Código (cpp) [Seleccionar]
   HWND hWnd = CreateWindowW(
   szWindowClass,
   szTitle,
   WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
   0,
   CW_USEDEFAULT,
   0,
   nullptr,
   nullptr,
   hInstance,
   nullptr);
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: srWhiteSkull en 7 Abril 2018, 20:40 PM
...tienes que usar la función SetWindowPos()

https://msdn.microsoft.com/es-es/library/a1yzfz6d.aspx
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 7 Abril 2018, 21:19 PM
Buenas:

No se ni donde poner ese código.

aaaa.cpp:
Código (cpp) [Seleccionar]
// 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:
Código (cpp) [Seleccionar]
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.
Código (cpp) [Seleccionar]
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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: srWhiteSkull en 7 Abril 2018, 21:50 PM
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;
}

Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 7 Abril 2018, 22:21 PM
Muchas gracias campeón.

Aún así me dice algo más de un error.

Código (cpp) [Seleccionar]
#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   
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: srWhiteSkull en 7 Abril 2018, 22:23 PM
A ver Mc fly, no deberías tener dos funciones de instancia  :rolleyes:
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 7 Abril 2018, 23:14 PM
Buenas:

El como lo hice me funciona pero no aparece botón ni cambio de tamaño del formulario.
Código (cpp,123,150) [Seleccionar]
// 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;
}
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: srWhiteSkull en 7 Abril 2018, 23:19 PM
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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 8 Abril 2018, 00:10 AM
Ejecuta pero no hace nada, misma pantalla, el tamaño, aunque lo varíe, no hace nada.

Código (cpp) [Seleccionar]
#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;
}
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: ivancea96 en 8 Abril 2018, 12:42 PM
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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 8 Abril 2018, 21:22 PM
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í.
Código (cpp) [Seleccionar]
#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:
Código (cpp) [Seleccionar]
#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.
Código (cpp) [Seleccionar]
mciSendString(L"set cdaudio door open", nullptr, 0, nullptr);

Cerrar bandeja.
Código (cpp) [Seleccionar]
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.
Código (cpp) [Seleccionar]
   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.
Código (cpp) [Seleccionar]
   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.
Código (cpp) [Seleccionar]
   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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: srWhiteSkull en 8 Abril 2018, 22:06 PM
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
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 8 Abril 2018, 22:11 PM
Editado, volver a leer el post anterior donde pone Edito:.

Falta este donde encajarlo bien.
Código (cpp) [Seleccionar]
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);
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: srWhiteSkull en 8 Abril 2018, 22:17 PM
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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: srWhiteSkull en 8 Abril 2018, 22:26 PM
https://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 8 Abril 2018, 23:56 PM
Buenas:

Por fin.
(https://www.subeimagenes.com/img/captura2-1852537.PNG)
Código (cpp) [Seleccionar]
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:
Código (cpp) [Seleccionar]
mciSendString("set CDAudio door open", rt, 127, IntPtr::Zero);

Cerrar:
Código (cpp) [Seleccionar]
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.
Código (cpp) [Seleccionar]
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.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 9 Abril 2018, 17:43 PM
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.
Código (cpp) [Seleccionar]
#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:
Código (cpp) [Seleccionar]

mciSendString("set CDAudio door open", rt, 127, IntPtr::Zero);



En el botón Cerrar:

Código (cpp) [Seleccionar]
mciSendString("set CDAudio door closed", rt, 127, IntPtr::Zero);


Si todo marcha bien, habremos acabado.
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 10 Abril 2018, 16:33 PM
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
Título: Re: ¿Cómo añadir dos botones al formulario?
Publicado por: Meta en 10 Abril 2018, 21:04 PM
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.

Código (cpp) [Seleccionar]
#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. ;)