I am so new to developing with Win32 API in C++, and I have made a first program like this:
Below is my code, but if you want to build it, then this is my project archive.
// The feedback interface with GUI.
#include "stdafx.h"
#include "Win32Project1.h"
#include <string>
#include <fstream>
#include <Windows.h>
#define MAX_LOADSTRING 65536
#include <strsafe.h>
HFONT defaultFont;
HWND hwnd2;
HWND Button;
HWND Help;
void ErrorExit(LPTSTR lpszFunction) //Function used for debugging
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR), 0);
}
LPWSTR Convert(const std::string& s)
{
LPWSTR ws = new wchar_t[s.size() + 1]; // +1 for zero at the end
copy(s.begin(), s.end(), ws);
ws[s.size()] = 0; // zero at the end
return ws;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
TCHAR Feedback[MAX_LOADSTRING];
std::string Msg;
std::string MsgTitle;
std::ofstream FeedbackFile;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
// Get UI font
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
// If we're compiling with the Vista SDK or later, the NONCLIENTMETRICS struct
// will be the wrong size for previous versions, so we need to adjust it.
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
defaultFont = CreateFontIndirect(&(ncm.lfMessageFont));
// Register the window class.
std::string CLASS_NAME = "The first program!";
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"First program!";
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
WS_EX_CONTEXTHELP, // Optional window styles.
L"First program!", // Window class
L"The first program!", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
0, 0, 640, 360,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Create the window.
hwnd2 = CreateWindowEx(
WS_EX_CLIENTEDGE, // Optional window styles.
L"edit", // Window class
L"Insert feedback here :)", // Window text
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_LEFT | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, // Window style
// Size and position
10, 50, 300, 200,
hwnd, // Parent window
(HMENU)(123), // Menu
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), // Instance handle
NULL // Additional application data
);
Button = CreateWindowW(
L"BUTTON",
L"Submit feedback!",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
160, 255, 150, 20,
hwnd,
(HMENU) BT_PRESS,
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
NULL
);
Help = CreateWindowW(
L"BUTTON",
L"What is this?",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
10, 280, 80, 20,
hwnd,
(HMENU)HELP_PRESS,
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
NULL
);
SendMessage(hwnd2, WM_SETFONT, WPARAM(defaultFont), TRUE);
SendMessage(Button, WM_SETFONT, WPARAM(defaultFont), TRUE);
SendMessage(Help, WM_SETFONT, WPARAM(defaultFont), TRUE);
if (hwnd2 == NULL)
{
return 0;
}
ShowWindow(hwnd2, nCmdShow);
// Run the message loop.
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_HELP:
MessageBox(Help, L"This is my first program made by Visual Studio 2017.\nYou can type your feedback in the box and then press Submit feedback!\nYour feedback will be saved and we will read it.\n\nThanks so much for using this program. :)", L"About this program", MB_OK);
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc, defaultFont);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
TextOut(hdc, 10, 5, TEXT("Hi! This is my first program made by Visual Studio 2017."), 57);
TextOut(hdc, 10, 20, TEXT("Do you have something to tell me?"), 34);
TextOut(hdc, 10, 35, TEXT("Just write below and I will listen. :)"), 39);
EndPaint(hwnd, &ps);
}
case WM_COMMAND:
{
switch (wParam)
{
case BT_PRESS:
{
GetWindowText(hwnd2, Feedback, MAX_LOADSTRING);
FeedbackFile.open("Feedback.txt", std::ios::out | std::ios::app);
FeedbackFile << Feedback;
FeedbackFile << "\n------------------------\n";
FeedbackFile.close();
LPWSTR Msg = L"Thanks for your feedback! I appreciated!";
LPWSTR MsgTitle = L"Feedback accepted!";
MessageBox(hwnd, Msg, MsgTitle, MB_OK);
SendMessage(hwnd, WM_DESTROY, NULL, NULL);
} break;
case HELP_PRESS:
SendMessage(hwnd, WM_HELP, 0, 0);
break;
}
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
I intended to make the program display a messagebox that tells the user about the program, then when click OK, the box closes and the program is still there. But when OK button is clicked, the messagebox disappeared, and the program closed either. Is there anyway to keep the program running after the user click OK? Thank you so much.