鱼C论坛

 找回密码
 立即注册
查看: 53|回复: 8

[已解决]窗口程序

[复制链接]
发表于 前天 20:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <Windows.h>       

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
        WNDCLASS wndclass;
        HWND hwnd;
        MSG msg;
        static TCHAR szClassName[] = TEXT("我的窗口");
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.lpfnWndProc = WndProc;
        wndclass.lpszClassName = szClassName;
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndclass.hInstance = hInstance;
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;

        if (!RegisterClass(&wndclass))
        {
                MessageBox(NULL, TEXT("提示:需要在NT系统下进行"), TEXT("警告"), MB_OK);
                return 0;
        }
        hwnd = CreateWindow(szClassName,
                TEXT("鱼C"),
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL);
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);
        while (GetMessage(&msg, hwnd, 0, 0))
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }
        return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;
        switch (message)
        {
        case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
                GetClientRect(hwnd, &rect);
                DrawText(hdc, TEXT("我的第一个窗口"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
                EndPaint(hwnd, &ps);
                return 0;
        /*case WM_LBUTTONDOWN:
                MessageBox(hwnd, TEXT("我被按了一下"), TEXT("haha"), MB_OK);
                return 0;
        */
       

        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
}

不停地点运行关闭,窗口的位置一直在变, 另外加上代码
case WM_CLOSE:
if(MessageBox(hwnd, TEXT("真的要关闭我吗"), TEXT("提示”), MB_YESNO)==IDYES)
DestroyWindow(hwnd);
else
return 0;
加上这个程序就崩溃
最佳答案
前天 21:10
1006150804 发表于 2025-01-08 21:10
某一个“天” 发表于 2025-1-8 20:32
if(MessageBox( ...


在消息循环中调用 `GetMessage` 函数时,将第二个参数指定为特定的窗口句柄 `hwnd` 会导致程序只接收该窗口的消息,而忽略其他全局消息。这可能导致无法正确处理 `WM_QUIT` 消息等全局消息,从而导致程序不能正常退出。

通常情况下,`GetMessage` 的第二个参数应为 `NULL`,这样可以确保获取应用程序的所有消息,而不仅仅是特定窗口的消息。修改你的代码如下:
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

将 `hwnd` 改为 `NULL` 可以确保程序正确接收和处理所有消息,包括帮助应用程序正常退出的 `WM_QUIT` 消息,从而避免无法关闭的情况发生。这样,程序能在窗口关闭后正确退出并释放资源。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 前天 20:29 | 显示全部楼层
在你的代码中,`case WM_CLOSE` 的处理方式有些问题,应该是因为双引号使用不一致导致的问题。我来帮助你修正这个问题,并确保你的程序不会崩溃。

请确保`case WM_CLOSE`部分的代码如下所示:
case WM_CLOSE:
    if (MessageBox(hwnd, TEXT("真的要关闭我吗"), TEXT("提示"), MB_YESNO) == IDYES)
        DestroyWindow(hwnd);
    else
        return 0;
    break;

注意几点:
1. 确保 `TEXT` 宏内的引号是一致的,例如 `TEXT("提示")`。
2. `return 0;` 后需要加上 `break;`,确保处理完 `WM_CLOSE` 消息后,不会继续执行后续的 `case` 语句。
3. 每个 `case` 语句后都保持有 `break;`,以防止意外的代码执行。

请根据修改后的代码重新编译并运行,这应该可以解决你遇到的崩溃问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 20:32 | 显示全部楼层
if(MessageBox(hwnd, TEXT("真的要关闭我吗"), TEXT("提示”), MB_YESNO)==IDYES)
后面的引号是中文
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 20:43 | 显示全部楼层
FishC 发表于 2025-1-8 20:29
在你的代码中,`case WM_CLOSE` 的处理方式有些问题,应该是因为双引号使用不一致导致的问题。我来帮助你修 ...

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
        WNDCLASS wndclass;
        HWND hwnd;
        MSG msg;
        static TCHAR szClassName[] = TEXT("我的窗口");
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.lpfnWndProc = WndProc;
        wndclass.lpszClassName = szClassName;
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndclass.hInstance = hInstance;
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;

        if (!RegisterClass(&wndclass))
        {
                MessageBox(NULL, TEXT("提示:需要在NT系统下进行"), TEXT("警告"), MB_OK);
                return 0;
        }
        hwnd = CreateWindow(szClassName,
                TEXT("鱼C"),
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL);
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);
        while (GetMessage(&msg, hwnd, 0, 0))
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }
        return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;
        switch (message)
        {
        case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
                GetClientRect(hwnd, &rect);
                DrawText(hdc, TEXT("我的第一个窗口"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
                EndPaint(hwnd, &ps);
                return 0;
                break;
        /*case WM_LBUTTONDOWN:
                MessageBox(hwnd, TEXT("我被按了一下"), TEXT("haha"), MB_OK);
                return 0;
        */
        case WM_CLOSE:
                if (MessageBox(hwnd, TEXT("真的要关闭我吗"), TEXT("提示"), MB_YESNO) == IDYES)
                        DestroyWindow(hwnd);
                else
                        return 0;
                break;

        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
                break;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
}
为什么我点关闭之后任务管理器里还是存在My Project的任务,而且存在好几个,但是程序依然可以运行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 20:43 | 显示全部楼层
1006150804 发表于 2025-01-08 20:43
FishC 发表于 2025-1-8 20:29
在你的代码中,`case W ...


你遇到的问题可能是多次创建了窗口而未正确销毁它们。请检查以下几点来解决问题:

1. **确保窗口正确销毁**:确保 `DestroyWindow(hwnd);` 语句在用户选择 "是" 后被正确执行。留意 `MessageBox` 的返回值。

2. **避免多次运行实例**:检查代码逻辑,或者项目设置,确保你的程序在运行时不生成多份实例。另外,关闭之前运行的实例窗口,确保测试时只有一个实例在运行。

3. **按序销毁窗口**:窗口销毁顺序(`WM_CLOSE` 然后 `WM_DESTROY`)必须遵循。仅当 `DestroyWindow(hwnd);` 执行成功时,才会发送 `WM_DESTROY` 消息。执行 `PostQuitMessage(0);` 保证关闭时应用程序退出消息循环。

请确认你的代码逻辑与项目设置中没有导致多窗口或多实例运行的因素。如依然存在问题,也可以通过系统日志或调试模式获取更多信息分析错误来源。

如果需要进一步协助,请确保提供运行环境的特定信息。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 21:10 | 显示全部楼层
某一个“天” 发表于 2025-1-8 20:32
if(MessageBox(hwnd, TEXT("真的要关闭我吗"), TEXT("提示”), MB_YESNO)==IDYES)
后面的引号是中文

不是这个原因,我在GetMessage里第二个参数写了窗口句柄,为什么写上hwnd运行几次就会崩溃呢,后台也关不掉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 21:10 | 显示全部楼层    本楼为最佳答案   
1006150804 发表于 2025-01-08 21:10
某一个“天” 发表于 2025-1-8 20:32
if(MessageBox( ...


在消息循环中调用 `GetMessage` 函数时,将第二个参数指定为特定的窗口句柄 `hwnd` 会导致程序只接收该窗口的消息,而忽略其他全局消息。这可能导致无法正确处理 `WM_QUIT` 消息等全局消息,从而导致程序不能正常退出。

通常情况下,`GetMessage` 的第二个参数应为 `NULL`,这样可以确保获取应用程序的所有消息,而不仅仅是特定窗口的消息。修改你的代码如下:
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

将 `hwnd` 改为 `NULL` 可以确保程序正确接收和处理所有消息,包括帮助应用程序正常退出的 `WM_QUIT` 消息,从而避免无法关闭的情况发生。这样,程序能在窗口关闭后正确退出并释放资源。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 21:11 | 显示全部楼层
FishC 发表于 2025-1-8 20:43
你遇到的问题可能是多次创建了窗口而未正确销毁它们。请检查以下几点来解决问题:

1. **确保窗口正 ...

找到原因了,我在GetMessage里第二个参数写了窗口句柄,为什么写上hwnd运行几次就会崩溃呢,后台也关不掉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 21:11 | 显示全部楼层
1006150804 发表于 2025-01-08 21:11
FishC 发表于 2025-1-8 20:43
你遇到的问题可能是多 ...


在 `GetMessage` 函数中,将第二个参数设置为特定的窗口句柄(如 `hwnd`)会使程序只接收来自该窗口的消息,而忽略所有其他全局消息。这会导致几个问题:

1. **`WM_QUIT` 消息无法接收**:如果 `GetMessage` 仅接收指定窗口的消息,那么全局的 `WM_QUIT` 消息就会被忽略。因此,当窗口关闭时,程序无法正常退出,导致后台有残留的任务。

2. **无法正确处理其他消息**:一些重要的系统消息可能不会传递到该窗口句柄,从而影响程序的正常运行。

3. **资源未释放**:没有正确处理 `WM_QUIT`,导致资源未释放,可能出现内存占用不断增加或者无法结束进程的情况。

正确的做法是将 `GetMessage` 的第二个参数设置为 `NULL`,以便接收整个应用程序范围内的所有消息,而不只是单一窗口的消息。如下所示:
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

这样,程序可以处理所有消息,也能正确响应 `WM_QUIT` 消息,实现程序正常退出,避免出现崩溃和无法关闭的问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-10 03:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表