CreateThread and classes

  asynchronous, c++, multithreading, static, winapi

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++

LEAVE A COMMENT