对话框回调函数的问题

Windows回调函数返回值解析
#include<windows.h>
#include"resource.h"
 
HWND hwnd_B;
HINSTANCE g_hInstance;
 
//函数声明
LRESULT CALLBACK Proc_A(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK Proc_B(HWND , UINT, WPARAM , LPARAM );
 
//主函数
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
     g_hInstance = hInstance;
     HWND hwnd_A = CreateDialog(g_hInstance,(LPCTSTR)(IDD_DIALOG_MAIN),NULL,(DLGPROC)Proc_A);
    
     ::SetWindowPos(hwnd_A, HWND_TOP, 250,200,540, 310, SWP_SHOWWINDOW);
     ::UpdateWindow(hwnd_A);
    
     MSG msg;
 
     if( NULL == hwnd_A )
     {
         ::MessageBox( NULL, "CreateWindow error", "error", MB_OK );
         return -1;
     }
 
     while (GetMessage(&msg, NULL, 0, 0))
     {
TranslateMessage(&msg);
         DispatchMessage(&msg);
     }
     return msg.wParam;
}
 
//回调函数A
LRESULT CALLBACK Proc_A(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
         case WM_INITDIALOG:
              {
                   return TRUE;
              }
         case WM_COMMAND:
              {
                   if (LOWORD(wParam) == IDOK)
                   {
                       hwnd_B = CreateDialogA( g_hInstance,
                            (LPCTSTR)(IDD_DIALOG_STUDENT),
                            hDlg,
                            (DLGPROC)Proc_B);
                       ::ShowWindow(hwnd_B,SW_SHOW);
                       ::UpdateWindow(hwnd_B);
                       return TRUE;
                   }
                   if (LOWORD(wParam) == IDCANCEL)
                   {
                       PostQuitMessage(0);
                       return TRUE; 
                   }
              }
         case WM_DESTROY:
              PostQuitMessage(0);
     }
    return FALSE;
}
 
//回调函数B
LRESULT CALLBACK Proc_B(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
         case WM_INITDIALOG:
              {
                   return TRUE;
              }
         case WM_COMMAND:
              {
                   if (LOWORD(wParam) == IDOK)
                   {
                       return TRUE;
                   }
                   if (LOWORD(wParam) == IDCANCEL)
                   {
                       EndDialog(hDlg, LOWORD(hwnd_B));
                       return TRUE; 
                   }
              }
         case WM_DESTROY:
              PostQuitMessage(0);
     }
    return FALSE;
}
 
 
 

 

代码如上,令我不解的是最后一行的return FALSE 。
 
起初我不小心写成了return TRUE ,紧接着问题就来了,显示的子窗口只有按钮被绘制,其余部分都是原来屏幕的内容。
调用 ::UpdateWindow(hwnd_B); 问题依旧。
主窗口只能被拖动,不响应任何消息(我明明用的是非模态对话框)。子窗口的其他分支返回 TRUE 就可以,百思不得其解,究竟这个返回值意味着什么呢?windows在回调函数返回后干了些什么呢?希望有高手为我解惑。
### WPF 对话框回调函数调用 API 无效的解决方案 在 WPF 中,对话框回调函数可能无法正确调用 API 的原因通常涉及以下几个方面:数据绑定问题、线程上下文限制、事件处理逻辑错误或 API 调用时机当。以下是一个完整的分析和解决方案: #### 1. 数据绑定与线程上下文 WPF 的控件运行在主线程中,而某些 API 可能需要在后台线程中执行。如果直接在 UI 线程上调用这些 API,可能会导致阻塞或其他异常行为。为了解决这个问题,可以使用 `Task` 或 `Dispatcher` 来确保正确的线程上下文[^1]。 ```csharp private async void Button_Click(object sender, RoutedEventArgs e) { string projectName = ProjectNameTextBox.Text; // 使用 Task.Run 将 API 调用放到后台线程 bool result = await Task.Run(() => ProjectManager.CreateProject(projectName)); if (result) { MessageBox.Show("项目创建成功!"); } else { MessageBox.Show("项目创建失败,请检查输入!"); } this.Close(); } ``` #### 2. 回调函数的正确实现 确保回调函数能够正确触发,并且逻辑清晰。例如,在按钮点击事件中调用 API,同时验证输入是否合法[^2]。 ```csharp private void Button_Click(object sender, RoutedEventArgs e) { if (string.IsNullOrWhiteSpace(ProjectNameTextBox.Text)) { MessageBox.Show("请输入有效的项目名称!"); return; } string projectName = ProjectNameTextBox.Text; // 调用 API 并处理结果 bool result = ProjectManager.CreateProject(projectName); if (result) { MessageBox.Show("项目创建成功!"); } else { MessageBox.Show("项目创建失败,请检查输入!"); } this.Close(); } ``` #### 3. API 调用时机 API 调用的时机非常重要。如果在对话框关闭后调用 API,可能导致资源释放或状态丢失的问题。因此,建议在对话框关闭前完成所有必要的操作[^3]。 ```csharp private void Button_Click(object sender, RoutedEventArgs e) { if (string.IsNullOrWhiteSpace(ProjectNameTextBox.Text)) { MessageBox.Show("请输入有效的项目名称!"); return; } string projectName = ProjectNameTextBox.Text; // 调用 API 并等待结果 bool result = ProjectManager.CreateProject(projectName); if (result) { MessageBox.Show("项目创建成功!"); } else { MessageBox.Show("项目创建失败,请检查输入!"); } // 确保在关闭对话框之前完成所有操作 this.DialogResult = true; this.Close(); } ``` #### 4. 错误处理与日志记录 为了更好地排查问题,可以在 API 调用过程中添加错误处理和日志记录功能。这有助于捕获潜在的异常并提供调试信息。 ```csharp private async void Button_Click(object sender, RoutedEventArgs e) { try { string projectName = ProjectNameTextBox.Text; // 调用 API 并处理结果 bool result = await Task.Run(() => ProjectManager.CreateProject(projectName)); if (result) { MessageBox.Show("项目创建成功!"); } else { MessageBox.Show("项目创建失败,请检查输入!"); } } catch (Exception ex) { MessageBox.Show($"发生错误: {ex.Message}"); // 记录日志 LogError(ex); } finally { this.Close(); } } private void LogError(Exception ex) { // 实现日志记录逻辑 } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值