开发者

Win32 GUI and callback to C++ function

开发者 https://www.devze.com 2023-02-18 11:51 出处:网络
So, basically I\'m using a code like this one. It\'s a little simple window where you can only change text inside of an edit box and press a button that will make a callback to a function (DoSomething

So, basically I'm using a code like this one. It's a little simple window where you can only change text inside of an edit box and press a button that will make a callback to a function (DoSomethingCallback(text)).

#include <windows.h>

#define ID_EDIT 1
#define ID_BUTTON 2

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

  static HWND hwndEdit;
  static HWND hwndButton;
  static int len;
  static TCHAR text[30];


  switch(msg)
  {
    case WM_CREATE:
    hwndEdit = CreateWindow(TEXT("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,
                50, 50, 150, 20, hwnd, (HMENU) ID_EDIT,
                NULL, NULL);

    hwndButton = CreateWindow(
开发者_开发知识库        TEXT("button"), TEXT("Set Title"),       
        WS_VISIBLE | WS_CHILD,  
        50, 100, 80, 25,        
        hwnd, (HMENU) ID_BUTTON, NULL, NULL);      

    break;

    case WM_COMMAND:    
           if (HIWORD(wParam) == BN_CLICKED) {
               SetWindowText(hwnd, "Working...");
               GetWindowText(hwndEdit, text, len);
               DoSomethingCallback(text);
               SetWindowText(hwnd, "Finished");
           }
    break;

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

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
            LPSTR lpCmdLine, int nCmdShow )
{
  MSG  msg ;    
  WNDCLASS wc = {0};
  wc.lpszClassName = TEXT( "Edit Control" );
  wc.hInstance     = hInstance ;
  wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  wc.lpfnWndProc   = WndProc ;
  wc.hCursor       = LoadCursor(0,IDC_ARROW);


  RegisterClass(&wc);
  CreateWindow( wc.lpszClassName, TEXT("Edit control"),
                WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                220, 220, 280, 200, 0, 0, hInstance, 0);  

  while( GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return (int) msg.wParam;
}

The problem is that when running that Callback the window will appear as "Not responsive" and even laggy if you try to close or press the button. I understand the reason why this might be happening, the callback takes time and the receiving loop isn't there to check the input of the user. I've searched a way to 'fix' this and I couldn't find any. I'm pretty sure it's something dumb, but I have to try and ask.

An obvious way would be making a faster callback. But is there another one like checking the user input inside of a DoSomethingCallback() while, or I have to use multiple threads?

Sorry for the confusing question.


I would go for calling QueueUserWorkItem() to handle it. If your DoSomethingCallback() is too long, there is no way to make your window responsive while DoSomethingCallback() is working since there is only one thread to run the code. Good Luck!


If possible, you can process the message queue at intervals within DoSomethingCallback which will keep the UI responsive. Just run the original message loop i.e. while( GetMessage(... whenever you can but make sure you disable the button so the user does not click a second time... this will lead to recursion.


You can peek at the message queue to convince windows that you are still alive and kicking, by calling PeekMessage() from time to time. This assumes that you can do this in your DoSomethingCallback(), i.e. that the main thread doesn't hang completely. Regard the loop below as pseudo code and use your imagination to transform it to your needs.

void DoSomethingCallback()
{
  // Loop that takes a long time
  while (true) {
    DoSomeStuff();
    MSG msg;
    PeekMessage(&msg, nil, 0, 0, PM_NOREMOVE);
    if (ShouldBreak()) {
      break;
    }
  }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消