【问题标题】:Created windows have no title [closed]创建的窗口没有标题[关闭]
【发布时间】:2017-07-02 04:34:33
【问题描述】:

我正在从我的控制台应用程序创建消息窗口。窗口类已正确注册并且窗口已正确创建,但它从来没有标题(而我的 createwindow 函数调用确实指定了标题)。 让我在想,控制台程序可以创建带有名称的窗口吗?谷歌了一下,一无所获。 这是我的代码,保持在最低限度:

using namespace std;
hInstance = GetModuleHandle(NULL);
WNDCLASS WndClass = {};
WndClass.style = CS_HREDRAW | CS_VREDRAW; // == 0x03
WndClass.lpfnWndProc = pWndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hIcon = 0;
WndClass.hCursor = 0;
WndClass.hbrBackground = (HBRUSH)COLOR_WINDOWFRAME;
WndClass.lpszMenuName = 0;
WndClass.lpszClassName = "EME.LauncherWnd";
int style = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | WS_THICKFRAME | WS_CAPTION;
if (RegisterClassA(&WndClass))
{
    cout << "class registered. Hinstance : " << hInstance <<  " style : (expect 0xcf0000) " << std::hex << style << endl;
    HWND hwind2 = CreateWindowExA(0, "EME.LauncherWnd", "Mytitle", style, 0x80000000, 0x80000000, 0x80000000, 0x80000000, NULL, NULL, hInstance, NULL);
    if (hwind2 == 0)
        cout << "Couldn't create window" << endl;
    else
        cout << "created window" << endl;
}

输出:

class registered. Hinstance : 00E40000
created window

使用 Nirsoft 的 Winlister 检查,该窗口存在,具有正确的类(“EME.LauncherWnd”),但没有名称。 此外,在块中添加这些代码行:

if (0 == SetWindowText(hwind2, "aTitle"))
            cout << "couldn't set a title" << endl;
        else
            cout << "title set " << endl;

输出是

title set

然而,窗口仍然没有标题。如果控制台程序没有标题,我假设 SetWindowText 调用将返回 0。 我究竟做错了什么 ? 编辑:根据要求添加 pWndProc

LRESULT CALLBACK pWndProc(HWND hwnd,            // Handle to our main window
    UINT Msg,             // Our message that needs to be processed
    WPARAM wParam,        // Extra values of message 
    LPARAM lParam)        // Extra values of message
{
        switch (Msg)

        {
    case WM_DESTROY: 
....
break; 
         }
}

虽然在注释指出 pWndProc(我认为该主体与窗口的构造无关)之后,事实证明将此代码行作为默认值插入到 switch case 中

return DefWindowProc(hwnd, Msg, wParam, lParam);

解决问题。

【问题讨论】:

标签: c++ winapi window


【解决方案1】:

我正在按照评论的建议发布问题的答案: 答案是要完成窗口创建,传递给 RegisterClass WINAPI 的 pWndProc 必须处理默认消息(特别是操作系统消息)。 在 CreateWindow 执行期间(在调用开始之后和返回之前),pWndProc 函数已经接收到它必须处理的消息,在我的例子中它没有处理它们。 这是一个标准的 pWndProc 函数:

LRESULT CALLBACK pWndProc(HWND hwnd,            // Handle to our main window
    UINT Msg,             // Our message that needs to be processed
    WPARAM wParam,        // Extra values of message 
    LPARAM lParam)        // Extra values of message
{
        switch (Msg)

        {
    case WM_DESTROY: 
...
    default:
        return DefWindowProc(hwnd, Msg, wParam, lParam);
         }
}

来源:

窗口过程通常不会忽略消息。如果它不处理消息,则必须将消息发送回系统进行默认处理。窗口过程通过调用 DefWindowProc 函数来执行此操作,该函数执行默认操作并返回消息结果。然后窗口过程必须将该值作为它自己的消息结果返回。大多数窗口过程只处理一些消息,并通过调用 DefWindowProc 将其他消息传递给系统。

【讨论】:

  • 嗯,很好奇它是否有效。不处理 WM_NCCREATE 通常也会结束它。嗯,消息窗口很特别,可能是为什么。您不应该设置他们的文本,因为没有人可以看到它,它们本来就是便宜的。像 Spy++ 这样的工具可以显示类名,已经足够好了。
  • @HansPassant 虽然询问者谈到了消息窗口,但他没有通过HWND_MESSAGE,所以这不是消息窗口。我想他只是希望把它移出屏幕,希望它不会被注意到!
  • 我实际上是在逆向设计一个程序以获取乐趣和知识(无利润)。我编写了自己的 MMORPG 启动器,其目的是在 5 秒内登录并启动游戏,而不是零售启动器的 1 分钟。我以与原始公司相同的方式创建了我的窗口(我在 createwindow 和 registerclass 上调试了他们的参数和函数调用)并且我使用了相同的标题/类名,这不取决于我。
猜你喜欢
  • 1970-01-01
  • 2012-03-25
  • 2016-03-13
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
相关资源
最近更新 更多