Reputation: 3405
I am new to the Win32 API. I have beginner questions.
How do I get and display values saved in a vector (mynum
) in wWinMain()
? How can I initialize it inside wWinMain()
?.
I did it as a global variable, but there must be a better way.
I am using DestroyWindow(hwnd);
inside the click event of a button, is this the correct way?
#include <windows.h>
#include <sstream>
#include<vector>
using namespace std;
#define ID_EDIT 1
#define ID_BUTTON 2
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
std::vector<int>mynum; // I don't want to initilze it here//
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR lpCmdLine, int nCmdShow) {
MSG msg;
WNDCLASSW wc = { 0 };
wc.lpszClassName = L"Edit control";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
wstringstream mg;
RegisterClassW(&wc);
CreateWindowW(wc.lpszClassName, L"Edit control",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
220, 220, 280, 200, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
mg<< L"Size: " << mynum.size()<<" 1:"<<mynum[0] << " 2: " << mynum[1];
int r= MessageBox(NULL, mg.str().c_str(), L"Erfolg", MB_OK | MB_ICONINFORMATION);
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static HWND hwndEdit1, hwndEdit2;
HWND hwndButton;
switch (msg) {
case WM_CREATE:
hwndEdit1 = CreateWindowW(L"Edit", NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER| ES_NUMBER,
50, 50, 50, 20, hwnd, (HMENU)ID_EDIT,
NULL, NULL);
hwndEdit2 = CreateWindowW(L"Edit", NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER,
50, 80, 50, 20, hwnd, (HMENU)ID_EDIT,
NULL, NULL);
hwndButton = CreateWindowW(L"button", L"Show vector",
WS_VISIBLE | WS_CHILD, 50, 120, 100, 25,
hwnd, (HMENU)ID_BUTTON, NULL, NULL);
break;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED) {
LONG num1 = GetWindowLong(hwndEdit1, GWL_STYLE);
mynum.push_back(num1);
LONG num2 = GetWindowLong(hwndEdit2, GWL_STYLE);
mynum.push_back(num2);
DestroyWindow(hwnd); **// IS IT CORRECT? //**
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
Upvotes: 0
Views: 525
Reputation: 597610
You can declare the vector
as a local variable inside of wWinMain()
, and then use the lpParam
parameter of CreateWindowW()
to pass a pointer to the vector
into your window procedure, eg:
#include <windows.h>
#include <sstream>
#include <vector>
using namespace std;
#define ID_EDIT 1
#define ID_BUTTON 2
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR lpCmdLine, int nCmdShow) {
WNDCLASSW wc = { 0 };
wc.lpszClassName = L"Edit control";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClassW(&wc);
vector<int> mynum;
CreateWindowW(wc.lpszClassName, L"Edit control",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
220, 220, 280, 200, 0, 0, hInstance, &mynum);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
wostringstream mg;
mg << L"Size: " << mynum.size();
for (size_t i = 0; i < mynum.size(); ++i) {
mg << " " << (i+1) << ":" << mynum[i];
}
int r = MessageBoxW(NULL, mg.str().c_str(), L"Erfolg", MB_OK | MB_ICONINFORMATION);
return static_cast<int>(msg.wParam);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static HWND hwndEdit1, hwndEdit2, hwndButton;
switch (msg) {
case WM_CREATE: {
CREATESTRUCT* pcs = reinterpret_cast<CREATESTRUCT*>(lParam);
vector<int> *vec = static_cast<vector<int>*>(pcs->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(vec));
hwndEdit1 = CreateWindowW(L"Edit", NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER| ES_NUMBER,
50, 50, 50, 20, hwnd, (HMENU)ID_EDIT,
NULL, NULL);
hwndEdit2 = CreateWindowW(L"Edit", NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER,
50, 80, 50, 20, hwnd, (HMENU)ID_EDIT,
NULL, NULL);
hwndButton = CreateWindowW(L"button", L"Show vector",
WS_VISIBLE | WS_CHILD, 50, 120, 100, 25,
hwnd, (HMENU)ID_BUTTON, NULL, NULL);
break;
}
case WM_COMMAND:
if (LOWORD(wParam) == ID_BUTTON && // or: reinterpret_cast<HWND>(lParam) == hwndButton
HIWORD(wParam) == BN_CLICKED) {
vector<int> *vec = reinterpret_cast<vector<int>*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
LONG num1 = GetWindowLong(hwndEdit1, GWL_STYLE);
vec->push_back(num1);
LONG num2 = GetWindowLong(hwndEdit2, GWL_STYLE);
vec->push_back(num2);
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
And yes, using DestroyWindow()
is correct, see Closing the Window:
The user can close an application window by clicking the Close button, or by using a keyboard shortcut such as ALT+F4. Any of these actions causes the window to receive a WM_CLOSE message. The WM_CLOSE message gives you an opportunity to prompt the user before closing the window. If you really do want to close the window, call the DestroyWindow function. Otherwise, simply return zero from the WM_CLOSE message, and the operating system will ignore the message and not destroy the window.
The alternative is to send the window a WM_CLOSE
message and let DefWindowProcW()
destroy the window for you:
However, there is a shortcut in this case. Recall that DefWindowProc executes the default action for any window message. In the case of WM_CLOSE, DefWindowProc automatically calls DestroyWindow. That means if you ignore the WM_CLOSE message in your switch statement, the window is destroyed by default.
//DestroyWindow(hwnd);
SendMessageW(hwnd, WM_CLOSE, 0, 0);
Upvotes: 2