构造函数字符串参数未设置窗口标题

Constructor string parameter not setting window title

本文关键字:设置 窗口标题 参数 字符串 构造函数      更新时间:2023-10-16

标题栏中的窗口标题未设置为我分配的变量和字符串。

我在下面展示了我的代码app::Window * wnd = new app::Window(L"Window Title");但问题是构造函数似乎确实是"tstring mWindowName";但这个mhWnd = CreateWindowEx(NULL, className.c_str(), mWindowName.c_str(), WS_OVERLAPPEDWINDOW, 100, 200, mScreenWidth, mScreenHeight, nullptr, nullptr, mhInstance, this);没有设置标题。

窗口.h

#ifndef _ST_Window_H_
#define _ST_Window_H_
// include files
//#include "s-window.h"
#include "s-platform.h"
#include "s-safe-delete-and-release.h"
#include "s-iostream.h"
#include "s-strings.h"
#ifndef _WINDOWS_
#include <windows.h>
#endif //_WINDOWS_
namespace app
{
class Window
{
protected:
    HINSTANCE mhInstance;
    HWND mhWnd;
    tstring mWindowName;
    bool mRunState;
    long int mScreenWidth;
    long int mScreenHeight;
public:
    Window(void);
    Window(tstring windowName);
    ~Window(void);
    int Setup(long int width, long int height);
    LRESULT MessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    int Run(void);
    inline HINSTANCE GetInstance(void) { return mhInstance; }
    inline HWND GetHwnd(void) { return mhWnd; }
    inline long GetWidth(void) { return mScreenWidth; }
    inline long GetHeight(void) { return mScreenHeight; }
    inline tstring GetWindowName(void) { return mWindowName; }
    inline bool GetRunState(void) { return mRunState; }
protected:
    int Create(void);
};
}
#endif //!_ST_Window_H_

窗口.cpp

// include files
#include "sit-window.h"
using namespace std;
namespace app
{
Window::Window(void) : mhInstance(GetModuleHandle(0)), mhWnd(nullptr), mWindowName(nullptr),
    mRunState(true), mScreenWidth(0), mScreenHeight(0) 
{
}
Window::Window(tstring windowName) : mhInstance(GetModuleHandle(0)), mhWnd(nullptr),
    mWindowName(windowName), mRunState(true), mScreenWidth(0), mScreenHeight(0) 
{
}
Window::~Window(void) 
{
}
int Window::Setup(long int width, long int height) 
{
    mScreenWidth = width;
    mScreenHeight = height;
    return Create();
}
LRESULT Window::MessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{
    switch (msg)
    {
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
}
LRESULT CALLBACK Window::WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{
    Window * wnd;
    if (msg == WM_NCCREATE)
    {
        CREATESTRUCT * pcs = (CREATESTRUCT*)lParam;
        wnd = (Window*)pcs->lpCreateParams;
        wnd->mhWnd = hwnd;
        SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pcs->lpCreateParams);
        return TRUE;
    }
    else
    {
        wnd = (Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    }
    if (wnd)
        return wnd->MessageProc(hwnd, msg, wParam, lParam);
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
int Window::Run(void)
{
    MSG msg = { 0 };
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return msg.wParam;
};
int Window::Create(void) {
    WNDCLASSEX wnd;
    SecureZeroMemory(&wnd, sizeof(WNDCLASSEX));
    wnd.cbClsExtra = NULL;
    wnd.cbSize = sizeof(WNDCLASSEX);
    wnd.cbWndExtra = NULL;
    wnd.hbrBackground = (HBRUSH)(COLOR_WINDOW + 3);
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wnd.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wnd.hInstance = mhInstance;
    wnd.lpfnWndProc = WindowProc;
    tstring className = mWindowName;
    className.append(L" - WndCls");
    wnd.lpszClassName = className.c_str();
    wnd.lpszMenuName = nullptr;
    wnd.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    if (!RegisterClassEx(&wnd))
    {
        std::wcout << L"Window class not registered!" << std::endl;
        mRunState = false;
        return 0x0;
    }
    RECT rect = { 0, 0, mScreenWidth, mScreenHeight };
    if (!AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, false, NULL))
    {
        std::wcout << L"Failed to adjust window rect!" << std::endl;
        mRunState = false;
        return 0x0;
    }
    else
    {
        mScreenWidth = rect.right;
        mScreenHeight = rect.bottom;
    }

    mhWnd = CreateWindowEx(NULL, className.c_str(), mWindowName.c_str(),
        WS_OVERLAPPEDWINDOW, 100, 200, mScreenWidth, mScreenHeight,
        nullptr, nullptr, mhInstance, this);
    if (!mhWnd)
    {
        std::wcout << L"Window not created!" << std::endl;
        mRunState = false;
        return 0x0;
    }
    if (ShowWindow(mhWnd, SW_SHOW))
    {
        std::wcout << L"Failed to show window!" << std::endl;
        mRunState = false;
        return 0x0;
    }
    if (!UpdateWindow(mhWnd))
    {
        std::wcout << L"Failed to update window!" << std::endl;
        mRunState = false;
        return 0x0;
    }
    if (!SetForegroundWindow(mhWnd))
    {
        std::wcout << L"Failed to set to foreground!" << std::endl;
        mRunState = false;
        return 0x0;
    }
    return 0x0;
}
}

主.cpp

// include files
//#include "s-safe-delete-and-release.h"
//#include "s-window.h"
#include "sit-window.h"
#include <iostream>
#include <string>
#include <windows.h>
#include <assert.h>
#pragma comment(lib, "serenity-core.lib")
// namespaces
using namespace std;
// statics
//long int srnty::Window::mScreenWidth = 1024;
//long int srnty::Window::mScreenHeight = 768;
// win main entry point
namespace win {
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    wcout << L"WinMain() called..." << endl;
    app::Window * wnd = new app::Window(L"Window Title");
    wnd->Setup(1024, 768);
    int result = wnd->Run();
    SafeDelete(wnd);
    return result; 
}
}
// main entry point
int main(int argv, char argc[])
{
// detect memory leaks in the application
#if defined(DEBUG) | defined(_DEBUG)
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(0);
int mlCount = _CrtDumpMemoryLeaks();
wcout << L"Number of memory Leaks: " << to_wstring(mlCount) << endl;
assert(mlCount == 0);
#endif
wcout << L"main() called..." << endl;
win::WinMain(GetModuleHandle(0), nullptr, nullptr, SW_SHOW);
wchar_t title[1024];
wchar_t titleBuffer[1024];
GetConsoleTitle(titleBuffer, 1024);
//wsprintf(title, L"%d", GetCurrentProcessId());    
SetConsoleTitle(title);
Sleep(40);
HWND hwndFound = FindWindow(NULL, title);
SetForegroundWindow(hwndFound);
system("pause");
return 0x0;
}

我希望tstring mWindowName;在这里使用时在标题栏中设置窗口标题mhWnd = CreateWindowEx(NULL, className.c_str(), mWindowName.c_str(), WS_OVERLAPPEDWINDOW, 100, 200, mScreenWidth, mScreenHeight, nullptr, nullptr, mhInstance, this);.tstring mWindowName;的初始化是通过 Main 中的构造函数进行的.cpp app::Window * wnd = new app::Window(L"Window Title");

正如上面的Raymond Chen明确指出的那样。这是我的疏忽。

在窗口中.cpp文件LRESULT CALLBACK Window::WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)从未返回控制DefWindowProc函数那里的永远不会设置标题。

功能应如下所示:

LRESULT CALLBACK Window::WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{
    Window * wnd;
    if (msg == WM_NCCREATE)
    {
        CREATESTRUCT * pcs = (CREATESTRUCT*)lParam;
        wnd = (Window*)pcs->lpCreateParams;
        wnd->mhWnd = hwnd;
        SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pcs->lpCreateParams);
        //return TRUE;
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    else
    {
        wnd = (Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    }
    if (wnd)
        return wnd->MessageProc(hwnd, msg, wParam, lParam);
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

谢谢,我希望这对其他人有所帮助。