(Winapi C ++)如何在没有全局变量的情况下将数据从窗口传递到窗口?

时间:2013-11-04 03:22:54

标签: c++ winapi

我试图对此进行研究,但我仍然很困惑。我真的不想使用全局变量,但即使在msdn网站上,他们也说“将其设置为全局以从对话框回调中访问它”。有没有我可以在堆上创建内存并将指针传递给新创建的对话框?我希望对话框能够更改通过指针访问的数据。

2 个答案:

答案 0 :(得分:4)

如果您使用的是DialogBoxParam,则可以在dwInitParam中传递指针:

DialogBoxParam(hInstance, 
               MAKEINTRESOURCE(IDD_DIALOG), 
               hwndParent, 
               YourDialogFunc, 
               dwInitParam);

然后您将从对话框回调中访问数据:

INT_PTR CALLBACK YourDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  switch(uMsg) [
    case WM_INITDIALOG:
      // the lParam parameter will contain the data sent through the dwInitParam
      return 1;
    break;
  }
  return 0;
}

如果您使用CreateWindowEx,则会通过lpCreateParams参数发送的CREATESTRUCT中的lpParam向您发送数据。

 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch(uMsg) [
      case WM_CREATE:
      {
        CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
        int* userdata = reinterpret_cast<int*>(pCreate->lpCreateParams);
        // store the pointer in the instance data of the window
        // so it could always be retrieved by using GetWindowLongPtr(hwnd, GWLP_USERDATA) 
        SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)userdata);
      }
      break;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
 }

答案 1 :(得分:0)

您始终可以将“PostMessage”与WM_USER(或任何消息值&gt; = WM_USER)一起使用,以在Windows之间发送自定义数据。 (SendWindow也可以工作,但它会有同步行为并阻塞,直到接收窗口消耗了消息)。

正如其他人在您的帖子和其他答案的评论中暗示的那样,可能有更好的方法来完成您真正想要做的事情。如果您只想将某些数据或数据对象与窗口句柄相关联,那么Krister提出的GWLP_USERDATA解决方案是标准的。

通常,PostMessage / SendMessage具有自定义消息类型和数据,用于从另一个线程或非UI组件发送信号。

但是这里有一些代码可以回答你原来的问题:

// sending window calls this
BYTE* data = malloc(DATA_BLOCK_SIZE);
// not shown - initialize "data"
PostMessage(hwndOtherDialog, WM_USER, 0, (LPARAM)data);

要接收它,该窗口的WndProc(或DlgProc)将按如下方式获取:

LRESULT __stdcall WndProcOtherWindow(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    case WM_USER:
    {
        BYTE* data = (BYTE*)lParam;

        // not shown - process data

        free(data);
        return 0;
    }