Windows Api - współrzędne klikniętego punktu

0

Cały program:

#ifndef UNICODE
#define UNICODE
#endif 

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    // Register the window class.
    const wchar_t CLASS_NAME[]  = L"Sample Window Class";
    
    WNDCLASS wc = { };

    wc.lpfnWndProc   = WindowProc;
    wc.hInstance     = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

    // Create the window.

    HWND hwnd = CreateWindowEx(
        0,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW,            // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
        );

    if (hwnd == NULL)
    {
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

    // Run the message loop.

    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
	case WM_LBUTTONDOWN:
		int xPos,yPos;
		xPos = GET_X_LPARAM(lParam); 
		yPos = GET_Y_LPARAM(lParam);
		
		MessageBox(0,L"You've pressed the left mouse button",L"Conrgatulations!",0);
		 


		break;
    case WM_DESTROY:
        PostQuitMessage(0);
		MessageBox(0,L"GoodBye!",L"Bye",0);
        return 0;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);

            FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

            EndPaint(hwnd, &ps);
        }
        return 0;

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

Chodzi mi głównie o tego MessageBox'a

 MessageBox(0,L"You've pressed the left mouse button",L"Conrgatulations!",0);

Co zrobić, żeby w treści komunikatu pokazywane były współrzędne punktu okienka w które kliknął użytkownik? Na razie debugger mówi:

1>c:\users\maciek\documents\visual studio 2010\projects\win32c++roughdraft\win32c++roughdraft\winmain.cpp(64): error C3861: 'GET_X_LPARAM': identifier not found
1>c:\users\maciek\documents\visual studio 2010\projects\win32c++roughdraft\win32c++roughdraft\winmain.cpp(65): error C3861: 'GET_Y_LPARAM': identifier not found

@Edit
W dokumentacji dopatrzyłem się, że makra GET_X_LPARAM oraz GET_Y_LPARAM wchodzą w skład biblioteki windowsX.h . Teraz procedura kliknięcia wygląda tak:

 case WM_LBUTTONDOWN:
		int xPos,yPos;
		xPos =LOWORD(lParam); 
		yPos = HIWORD(lParam);
		
		char buffer[150];

		sprintf(buffer, "You've pressed the left mouse button at the : x=%d , y=%d" , xPos , yPos);  

		MessageBoxW(0,(LPCWSTR)buffer,L"Congratulations!",0);
		 


		break;

Po skompilowaniu i kliknięciu w interaktywne pole utworzonego okienka pojawia się wiadomość , która w nagłówku posiada "Congratulations" a w treści jakieś chińskie znaki :(

Tylko nie mówcie żeby zamienić na funkcję MessageBoxA. Chyba nie muszę tłumaczyć dlaczego ta metoda jest mega-lamerska ;)

2

Używanie na sztywno funkcji w wersjach Unicode też jest lamerskie, choć trochę mniej niż trzymanie się ANSI.
Sam się z tym pogubiłeś, bo funkcji w wersji Unicode podajesz napis w ANSI (nie, rzutowanie na LPCWSTR nie dokona konwersji). Zamiast dać jej bezpośrednio napis Unicode, polecam używać TCHAR, zależnego od zdefiniowania UNICODE.
Istnieje wiele wersji funkcji operujących na napisach. Te, które szukasz to _sntprintf_s bądź StringCchPrintf. W zasadzie, działają one prawie identycznie, z czym ta pierwsza należy ogólnie do biblioteki standardowej w Windows, a ta druga bardziej do WinAPI. Od zwykłego sprintf różnią się tym, że działają i na ANSI i na Unicode i są bardziej bezpieczne (nie pozwalają na buffer overrun). Więcej znajdziesz na MSDN.

TCHAR buffer[150];
StringCchPrintf(buffer, 150, TEXT("You've pressed the left mouse button at the : x=%d , y=%d"), xPos, yPos);
MessageBox(0, buffer, TEXT("Congratulations!"), 0);
0

dzięki za pomoc, teraz działa .

Zanim jednak zaptaszkuję ten temat chciałbym rozważyć jeszcze jedną kwestię:

nie, rzutowanie na LPCWSTR nie dokona konwersji

Dlaczego ? Przecież byłoby dużo prościej i przyjemniej, nie trzeba by było korzystać z jakichś cudacznych bibliotek i funkcji :(.

à propos ANSI- jaki jest sens używania tego kodowania, skoro domyślnym kodowaniem w windows 6.1 jest bodajże utf-16 . Czyli wszystkie funkcje z postfiksem 'A' w rzeczywistości tłumaczą wszystko na unikod.

I jeszcze jedna sprawa - po każdym naciśnięciu w "client zone" okienka pojawia się kolejny komunikat, a więc jak trochę pobawimy się programem to powstaje ich pokaźny wężyk ;) . Czy jest możliwe aby wyjście następnego komunikatu zamykało poprzedni?

1 użytkowników online, w tym zalogowanych: 0, gości: 1