I need to create class that contains LRESULT CALLBACK WndProc. Exactly I am creating console application. Then call class-member function (createWindow) that create window using WNDCLASS. There can be a lot of windows with different names, buttons, etc. I am calling function, then it calls static _WndProc that calls non-static WndProc and creating buttons, menus, etc.
But I need create Window from CreateThread. CreateThread must get STATIC createWindow. If I create static createWindow, windows’ names and buttons will be same.
How can I fix that to create any windows with different data in it (text, buttons)?
Probably I need ASYNC windows.
Code (in the end is CreateThread):
std::string to_string(const std::wstring& str,
const std::locale& loc = std::locale())
{
std::vector<char> buf(str.size());
std::use_facet<std::ctype<wchar_t>>(loc).narrow(str.data(),
str.data() + str.size(),
'?', buf.data());
return std::string(buf.data(), buf.size());
}
std::wstring to_wstring(const std::string& str,
const std::locale& loc = std::locale())
{
std::vector<wchar_t> buf(str.size());
std::use_facet<std::ctype<wchar_t>>(loc).widen(str.data(),
str.data() + str.size(),
buf.data());
return std::wstring(buf.data(), buf.size());
}
enum styles {
STANDART = WS_CAPTION,
FREEZE = WS_POPUP,
BORDERED = WS_BORDER,
RESIZABLE = WS_SIZEBOX
};
class window {
public:
std::vector<std::wstring> button_names;
std::vector<int> button_ids;
std::vector<int> button_x;
std::vector<int> button_y;
std::vector<int> button_w;
std::vector<int> button_h;
std::vector<int> button_lines;
LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message)
{
case WM_CHAR: //this is just for a program exit besides window's borders/task bar
if (wparam == VK_ESCAPE)
{
DestroyWindow(hwnd);
}
case WM_CREATE:
for (int i = 0; i < button_names.size(); i++) {
CreateWindow(L"button", button_names[i].c_str(), WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE,
button_x[i], button_y[i], button_w[i], button_h[i], hwnd, (HMENU)button_ids[i], NULL, NULL);
}
return 0;
case WM_COMMAND:
//std::cout << wparam << " << CLICKEDn";
for (int i = 0; i < button_ids.size(); i++) {
if ((HIWORD(wparam) == 0) && (LOWORD(wparam) == button_ids[i])) {
std::wstring PARAM1 = L"You pressed button with LE ";
environment_32bit::ram.$LINE_COUNTER = button_lines[i];
PARAM1 += std::to_wstring(button_lines[i]);
MessageBox(hwnd, PARAM1.c_str(), L"MessageBox", MB_OK | MB_ICONWARNING);
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, message, wparam, lparam);
}
return 0;
}
static LRESULT CALLBACK _WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (WM_NCCREATE == message)
{
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)((CREATESTRUCT*)lparam)->lpCreateParams);
return TRUE;
}
return ((window*)GetWindowLongPtr(hwnd, GWLP_USERDATA))->WndProc(hwnd, message, wparam, lparam);
}
int LISTENER = 0;
int sx = 0;
int sy = 0;
int x = 0;
int y = 0;
int TYPE = 0;
HANDLE THREADED;
HWND handle;
HINSTANCE hInstance;
std::wstring name;
int getFullX() {
return GetSystemMetrics(SM_CXSCREEN);
}
int getFullY() {
return GetSystemMetrics(SM_CYSCREEN);
}
void setType(int T) {
TYPE = T;
}
void closeWindow() {
CloseWindow(handle);
}
void needResize() {
if (LISTENER >= button_names.size()) {
button_names.resize(LISTENER + 1);//
button_ids.resize(LISTENER + 1);
button_x.resize(LISTENER + 1);
button_y.resize(LISTENER + 1);
button_w.resize(LISTENER + 1);
button_h.resize(LISTENER + 1);
button_lines.resize(LISTENER + 1);
}
}
void setName(std::wstring wstr) {
needResize();
button_names[LISTENER] = wstr;
button_ids[LISTENER] = LISTENER;
}
void setX(int bx) {
needResize();
button_x[LISTENER] = bx;
}
void setY(int by) {
needResize();
button_y[LISTENER] = by;
}
void setW(int bw) {
needResize();
button_w[LISTENER] = bw;
}
void setH(int bh) {
needResize();
button_h[LISTENER] = bh;
}
void setListener(int line) {
needResize();
button_lines[LISTENER] = line;
}
void BUILD() {
LISTENER++;
}
void RemoveConsoleHWND() {
FreeConsole();
}
int qw = 0;
void increase() {
qw += 1;
}
DWORD WINAPI CreateWindow(LPVOID T) {
//int threadProc() {
WNDCLASS windowClass = { 0 };
windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hInstance = NULL;
windowClass.lpfnWndProc = _WndProc;
windowClass.lpszClassName = name.c_str();
windowClass.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&windowClass))
MessageBox(NULL, L"Could not register class", L"Error", MB_OK);
handle = CreateWindowW(name.c_str(),
NULL,
TYPE,
sx,
sy,
x,
y,
NULL,
NULL,
NULL,
this);
SetWindowText(handle, name.c_str());
ShowWindow(handle, SW_RESTORE);
MSG messages;
while (GetMessage(&messages, NULL, 0, 0) > 0)
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
DeleteObject(handle); //doing it just in cases
return messages.wParam;
}
};
std::vector<window> windows;
}
//CODE...
//Call CreateThread:
int main() {
CreateThread(NULL, 0, constructor::windows[_c].CreateWindow, NULL, 0, NULL);
// if threadProc static it is ok, but data for all windows will be the same
}
Source: Windows Questions C++