Red de conocimiento informático - Material del sitio web - Cómo abrir un cuadro de diálogo de entrada en la consola usando lenguaje C

Cómo abrir un cuadro de diálogo de entrada en la consola usando lenguaje C

#include

#include

HINSTANCE _HInstance // Identificador de la aplicación

TCHAR _Title[] = _T("Simple Text Box"); // Definir el título de la ventana

TCHAR _WindowClass[] = _T("MySimpleTextBoxApp" // Nombre de la clase de la ventana principal

ATOM _RegisterClass(); // Registra la clase de ventana principal

HWND _CreateWindow(int nCmdShow); // Crea la ventana principal

LRESULT CALLBACK _WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // Función de procesamiento de mensajes de la ventana principal

TCHAR _TextBoxClass[] = _T("MySimpleTextBox"); // Nombre de clase del cuadro de texto

ATOM _RegisterTextBoxClass() ; // Registra la clase de cuadro de texto

HWND _CreateTextBoxWindow(HWND hParentWnd); // Crea un cuadro de texto

LRESULT CALLBACK _TextBoxWndProc(HWND hWnd, mensaje UINT, WPARAM wParam , LPARAM lParam) ; // Función de procesamiento de mensajes de la ventana del cuadro de texto

void _DrawText(HDC hDC); // Dibujar texto

void _SetCaretPos(HWND hWnd);

void _UpdateWindow(HWND hWnd); // Actualizar ventana

// Algunas definiciones de constantes

#define MAINWINDOW_WIDTH 400 // Ancho de la ventana principal

# define MAINWINDOW_HEIGHT 200 // Alto de la ventana principal

#define TEXTBOX_WIDTH 300 // Ancho del cuadro de texto

#define TEXTBOX_HEIGHT 20 // Alto del cuadro de texto

#define TEXTBOX_MAXLENGTH 1024 // Longitud máxima del texto en el cuadro de texto

TCHAR _String[TEXTBOX_MAXLENGTH + 1] = _T(""); // Texto

int _StringPosition = : :_tcslen(_String) ; // La posición del punto de inserción del cursor

int APIENTRY _tWinMain(HINSTANCE hInstance, //La aplicación actual

Identificador de secuencia

HINSTANCE hPrevInstance, // Identificador de la instancia de la aplicación anterior (siempre NULL en Win32)

LPTSTR lpCmdLine, // Parámetros de la línea de comando

int nCmdShow // Estilo de visualización de la ventana

)

{

_HInstance = hInstance;

_RegisterClass() // Registrar clase de ventana

if(_CreateWindow(nCmdShow) == NULL) // Crear ventana

return FALSE;

MSG msg;

while (:: GetMessage(&msg, NULL, 0, 0)) // Obtener el mensaje de la cola de mensajes

{

::TranslateMessage(&msg); p>

::DispatchMessage(&msg); //Realizar procesamiento de mensajes

}

return (int)msg.wParam;

}

//Registrar clase de ventana de aplicación

ATOM _RegisterClass()

{

WNDCLASSEX wc;

::ZeroMemory (&wc, sizeof(wc)); // Como limpieza en un solo paso, el valor predeterminado de los campos no asignados es (o NULL)

wc.cbSize = sizeof(wc );

wc.style = CS_HREDRAW | CS_VREDRAW; // Especifica que la ventana se volverá a dibujar cuando cambien las dimensiones horizontales y verticales de la ventana

wc.hInstance = _HInstance;

wc .hbrBackground = (HBRUSH)( COLOR_APPWORKSPACE + 1); // Especifique el fondo de la ventana principal como el color del sistema del "área de trabajo"

wc.lpszClassName = _WindowClass; // Este se registrará como nombre de clase, utilice este nombre de clase como identificador al crear una ventana

wc.lpfnWndProc = _WndProc; // Esta es una función que maneja los mensajes de la ventana

return ::RegisterClassEx(&wc) / / Llamar a la función API para registrar la clase de ventana

}

// Crear ventana

HWND _CreateWindow(int nCmdShow)

{< / p>

HWND hWnd = ::CreateWindow(_WindowClass, _Title, WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT, MAINWINDOW_WIDTH, MAINWINDOW_HEIGHT, NULL, NULL, _HInstance, NULL);

if (hWnd == NULL)

return NULL;

::ShowWin

dow(hWnd, nCmdShow);

::UpdateWindow(hWnd);

return hWnd;

}

// Procesamiento de ventanas Procedimiento

LLAMADA DE RESULTADO _WndProc(HWND hWnd, mensaje UINT, WPARAM wParam, LPARAM lParam)

{

HWND estático hTextBoxWnd;

switch (mensaje)

{

case WM_CREATE: {

_RegisterTextBoxClass() // Registra la clase del cuadro de texto

hTextBoxWnd = _CreateTextBoxWindow(hWnd); // Crea un cuadro de texto

} break;

case WM_ACTIVATE: // Cuando la ventana está activada, establece el foco en el cuadro de texto

::SetFocus(hTextBoxWnd);

break;

case WM_SETCURSOR: { // Establece la forma del cursor

static HCURSOR hCursor = ::LoadCursor(NULL , IDC_ARROW);

::SetCursor(hCursor);

} break;

case WM_DESTROY: // La aplicación está cerrada

::PostQuitMessage(0);

romper;

predeterminado:

return ::DefWindowProc(hWnd, message, wParam, lParam);

}

return (LRESULT)0;

}

// Registra la clase del cuadro de texto

ATOM _RegisterTextBoxClass( )

{

WNDCLASSEX wc;

::ZeroMemory(&wc, tamañode(wc));

wc.cbTamaño = tamañode (wc);

wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS // Especifica volver a dibujar la ventana cuando el tamaño de la ventana cambia y responde al evento de doble clic del mouse

wc .hInstance = _HInstance;

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // Especifica el color de fondo de la ventana como el color del sistema "Fondo de la ventana"

wc.lpszClassName = _TextBoxClass; // Especifique el nombre de la clase de ventana que se registrará y utilice este nombre de clase como identificador al crear la ventana

wc.lpfnWndProc = _TextBoxWndProc // Función para procesar mensajes de ventana

return ::RegisterClassEx (&wc); // Llama a la función API para registrar la ventana del cuadro de texto

}

// Crea un cuadro de texto

HWND _CreateTextBoxWindow(HWND hParentWnd)

p>

{

// El siguiente código es para mostrar el cuadro de texto en el centro de la ventana principal y calcular la posición

RECT parentWndRect;

: :GetClientRect(hParentWnd, &parentWndRect); // Obtiene la ubicación del área de cliente de la ventana principal

int left = (parentWndRect.right - TEXTBOX_WIDTH) / 2, top = (parentWndRect) .bottom - TEXTBOX_HEIGHT) / 2;

// Crear cuadro de texto

HWND hWnd = ::CreateWindow(_TextBoxClass, NULL, WS_CHILDWINDOW | WS_VISIBLE,

izquierda , arriba, TEXTBOX_WIDTH, TEXTBOX_HEIGHT,

p>

hParentWnd, NULL, _HInstance, NULL);

return hWnd;

}

// Proceso de procesamiento de mensajes de cuadro de texto

LRESULT CALLBACK _TextBoxWndProc(HWND hWnd, mensaje UINT, WPARAM wParam, LPARAM lParam)

{

switch (mensaje)

{

case WM_PAINT: { // La razón por la que se agregan un par de llaves aquí es para localizar las variables definidas a continuación

static PAINTSTRUCT ps;

static RECT rect;

HDC hDC = ::BeginPaint(hWnd, &ps); // Iniciar operación de dibujo

::GetClientRect(hWnd, &rect); // Obtener el tamaño del área del cliente

::DrawEdge(hDC, &rect, EDGE_SUNKEN, BF_RECT); // Dibujar el borde, EDGE_SUNKEN indica que el estilo de dibujo es un estilo en línea, BF_RECT indica que el se dibuja el borde rectangular

_DrawText(hDC); // Dibujar texto

::EndPaint(hWnd, &ps); // Finalizar la operación de dibujo

} break;

case WM_SETFOCUS: { // Obtener el foco

::CreateCaret(hWnd, (HBITMAP)NULL, 1, TEXTBOX_HEIGHT-5 // Crear cursor

);

_SetCaretPos(hWnd); // Establece la posición del cursor

::ShowCaret(hWnd); //Mostrar cursor

} break;

case WM_KILLFOCUS : //Perdió el foco

::HideCaret(hWnd ); // Oculta el cursor

::DestroyCaret() // Destruye el cursor

break ;

case WM_SETCURSOR: { // Establece la forma del cursor

p>

estático HCURSOR hCursor = ::LoadCursor(NULL, IDC_IBEAM);

::SetCursor(hCursor);

} descanso;

caso WM_CHAR: { //Mensaje de carácter

TCHAR code = (TCHAR)wParam;

int len ​​​​= ::_tcslen(_String);

if(code < (TCHAR )' ' || len >= TEXTBOX_MAXLENGTH)

return 0;

::MoveMemory(_String + _StringPosition + 1, _String + _StringPosition, (len - _StringPosition + 1) * sizeof (TCHAR));

_String[_StringPosition ++] = código;

_UpdateWindow(hWnd);

_SetCaretPos(hWnd);

} break;

case WM_KEYDOWN: { // Mensaje de pulsación de tecla

Código TCHAR = (TCHAR)wParam;

cambiar (código)

p>

{

case VK_LEFT: // Tecla de cursor izquierda

if(_StringPosition > 0)

_StringPosition --;

break;

case VK_RIGHT: //Tecla de cursor derecho

if(_StringPosition < (int)::_tcslen(_String))

_StringPosition ++ ;

break;

case VK_HOME: // tecla INICIO

_StringPosition = 0;

break;

case VK_END: ​​​​// tecla END

_StringPosition = ::_tcslen(_String);

break;

case VK_BACK: // Tecla de retroceso

p>

if(_StringPosition > 0)

{

::MoveMemory(_String + _StringPosition - 1, _String + _StringPosition, (::_tcslen (_String)-_StringPosition + 1) * sizeof(TCHAR));

_StringPosition --;

_UpdateWindow(hWnd);

}

break;

case VK_DELETE: { // Eliminar clave

int len ​​​​= ::_tcslen(_String);

if(_StringPosition < len)

{

::MoveMemory(_String + _StringPosition, _String + _StringPosition + 1, (::_tcslen(_String) - _StringPosition

+ 1) * sizeof(TCHAR));

_UpdateWindow(hWnd);

}

} descanso;

}

_SetCaretPos(hWnd);

} break;

case WM_LBUTTONDOWN: { // Clic del mouse para establecer la posición del cursor

int x = LOWORD (lParam);

HDC hDc = ::GetDC(hWnd);

int strLen = ::_tcslen(_String), strPos = 0;

TAMAÑO tamaño;

for (strPos=0; strPos

{

::GetTextExtentPoint(hDc, _String, strPos, &size); /p>

if(size.cx + 4 >= x)

break;

}

_StringPosition = strPos;

::GetTextExtentPoint(hDc, _String, strPos, &size);

::SetCaretPos(size.cx + 4, 3);

::ReleaseDC(hWnd, hDc ) ;

} descanso;

predeterminado:

return ::DefWindowProc(hWnd, message, wParam, lParam);

}

return (LRESULT)0;

}

//Ventana de actualización

void _UpdateWindow(HWND hWnd)

{

RECT rect;

::GetClientRect(hWnd, &rect);

::InvalidateRect(hWnd, &rect, TRUE);

::UpdateWindow(hWnd);

}

// Dibujar texto

void _DrawText(HDC hDC)

{

int len ​​​​= ::_tcslen(_String);

::TextOut(hDC, 4, 2, _String, len);

}< / p>

//Establece la posición del cursor

void _SetCaretPos(HWND hWnd)

{

HDC hDC = ::GetDC(hWnd);

p>

SIZE tamaño;

::GetTextExtentPoint(hDC, _String, _StringPosition, &size);

::SetCaretPos(4 + size.cx, 3 );

p>

::ReleaseDC(hWnd, hDC);

}