Paulo RB

Windows Messages em C++/CLI Form

by paulorb on fev.07, 2012, under C++/CLI

Quando precisamos usar funções que trabalham com os windows messages, como PostMessage e SendMessage temos sempre que lembrar que programas em windows são baseados em eventos que são tratados no Message Loop como no exemplo abaixo:


    #include <Windows.h>

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

    int WINAPI WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    PSTR szCmdLine,
    int iCmdShow
    )
    {
    static TCHAR szAppName [] = TEXT("HelloWindows");
    HWND hwnd;
    MSG msg;
    WNDCLASS wndClass;

    wndClass.style = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = WndProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hInstance = hInstance;
    wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = szAppName;

    if (!RegisterClass(&wndClass))
    {
    MessageBox(NULL, TEXT("Error registering class."), szAppName, MB_ICONERROR);
    return 0;
    }

    hwnd = CreateWindow(szAppName,
    TEXT("The Hello Windows Native Programming"),
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    NULL,
    NULL,
    hInstance,
    NULL
    );

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 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("Hello, Windows Native Programming!"), -1, &rect,
    DT_SINGLELINE | DT_CENTER | DT_VCENTER);

    EndPaint(hwnd, &ps);
    return 0;

    case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
    }

Agora vamos imaginar o seguinte cenario, você está desenvolvendo uma aplicação em C++/CLI que se  integrará com uma API externa em .net , essa API tem uma propriedade chamada windowHandle onde você  precisa passar um Handle válido de uma janela, o objetivo dessa API é te fornecer uma forma de receber requisições assincronas por isso tem um evento Changed que sera chamado sempre que uma nova requisição chegar, o problema que irei relatar nesse post é o de que não é so criar uma janela  e chamar o metodo Show e esperar os eventos chegarem.    Veja o exemplo abaixo essa foi a primeira tentativa que NAO FUNCIONOU, o metodo VariableValue_Changed nunca é chamado.

Form ^formDispather = gcnew Form();
API::Variable::VariableComp declaredAPI;
 declaredAPI = gcnew API::Variable::VariableComp();
 declaredAPI->WindowHandle = formDispather->Handle;
 declaredAPI->Changed += gcnew System::EventHandler(this,&NameOftheClass::VariableValue_Changed);
 formDispather->Show();

Olhe agora a milionesima tentativa que funcionou. Perceba a diferença!

Form ^formDispather = gcnew Form();
API::Variable::VariableComp declaredAPI;
 declaredAPI = gcnew API::Variable::VariableComp();
 declaredAPI->WindowHandle = formDispather->Handle;
 declaredAPI->Changed += gcnew System::EventHandler(this,&NameOftheClass::VariableValue_Changed);
Application::Run(formDispather);

Perceba que a diferença é so que no primeiro que não funcionou eu usei o metodo Show do Form e no segundo que funcionou eu usei o Application::Run eis agora a explicação de porque funcionou: o aplication run inicia uma “aplication message loop” que trata as window messages enquanto o metodo show somente não faz isso. Isso me custou horas e horas de alguns colegas. Referencia para nunca cometer esse erro: http://msdn.microsoft.com/pt-br/library/ms157901(v=vs.90).aspx

:,

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Calendário

dezembro 2017
S T Q Q S S D
« mar    
 123
45678910
11121314151617
18192021222324
25262728293031