WinApi - promień zadany przez użytkownika

0

Cześć piszę sobie taki malutki programik w WinApi. Chodzi o to, że mam pole tekstowe i button, do pola tekstowego podaje sobie długość promienia i wciskam button zatwierdzający wolę użytkownika. Zmienna ta jest konwertowana na C-String i wędruje do tablicy znaków, aby następnie mogła zostać wyświetlona w MessageBoxie informującym użytkownika o długości promienia podanej przed chwilą (gdyby użytkownik np. zapomniał :D ) No dobra tyle mam. Dalej chciałbym aby ten promień się narysował :D Nie wiem za bardzo jak to zrobić, więc proszę o wskazówki. Oto kod programu:

 
#include <windows.h>
#include <stdlib.h>

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
int GetIntFromEdit(HWND hEdit);

char szClassName[ ] = "CodeBlocksWindowsApp";
HINSTANCE *hInst;
HWND hEdit, hButton;
HDC kon;
PAINTSTRUCT ps;
INT promien;
BOOL czy_podano = false;

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;
    hInst = &hThisInstance;

    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);

    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    if (!RegisterClassEx (&wincl))
        return 0;

    hwnd = CreateWindowEx (
           0,
           szClassName,
           "Code::Blocks Template Windows App",
           WS_OVERLAPPEDWINDOW,
           CW_USEDEFAULT,
           CW_USEDEFAULT,
           544,
           375,
           HWND_DESKTOP,
           NULL,
           hThisInstance,
           NULL
           );

    ShowWindow (hwnd, nCmdShow);

    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }

    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_CREATE:
            hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER, 20, 30, 80, 25, hwnd, NULL, *hInst, NULL);
            hButton = CreateWindowEx(0, "BUTTON", "DO IT!", WS_CHILD | WS_VISIBLE, 20, 65, 90, 30, hwnd, NULL, *hInst, NULL);
            break;
        case WM_PAINT:
            kon = BeginPaint( hwnd, & ps );
            TextOut( kon, 20, 10, "Podaj promien", 13 );
            break;
        case WM_COMMAND:
            if((HWND) lParam == hButton)
            {
                promien = GetIntFromEdit(hEdit);
                char tablica[24];
                itoa(promien, tablica, 10);
                MessageBox(hwnd, tablica, "Promien", MB_ICONINFORMATION);
                czy_podano = true;
            }

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

    return 0;
}

int GetIntFromEdit(HWND hEdit)
{
   int textLength = GetWindowTextLength(hEdit) + 1;
   char *textBuffer = new char[textLength];
   GetWindowText(hEdit, textBuffer, textLength);

   return atoi(textBuffer);
}
0

A możesz narysować przykładowy promień w paint? Niezbyt rozumiem o jaki rysunek promienia ci chodzi.

0

MoveTo + LineTo rysuje linię

char *textBuffer = new char[textLength]; // a delete to pies zjadł?

0

No dobra zwolniłem pamięć :) Problem jednak nadal obowiązuje, dodałem właśnie pare linijek:

 
if(czy_podano)
            {
                HDC hdcOkno;
                hdcOkno = GetDC( hwnd );
                POINT stary_punkt;
                MoveToEx( hdcOkno, 10, 10, & stary_punkt );
                LineTo( hdcOkno, 21, 10 );
            }
0

Ale jaki problem?

0

//globalnie

 
BOOL rysowac_promien = false;
 
case WM_PAINT:
{
     PAINTSTRUCT ps;
     HDC hdc = BeginPaint(hwnd, &ps);
     if(!rysowac_promien)
     {
          //tu rysujesz cos kiedy nie mamy promienia rysowac
     }
     else
     {
          //a tu jeśli mamy rysowac promień
     }
     EndPaint(hwnd, &ps);
     break;
}

W twoim kodzie w obsłudze komunikatu WM_PAINT brakuje EndPaint() , równolegle do BeginPaint().
Wszystko o rysowaniu prostych obiektów graficznych opisane jest tutaj.
http://www.google.pl/url?sa=t&rct=j&q=winapi%20grafika&source=web&cd=1&cad=rja&ved=0CCsQFjAA&url=http%3A%2F%2Fcpp0x.pl%2Fkursy%2FKurs-WinAPI-C%2B%2B%2FPodstawy%2FGrafika%2F181&ei=9O0DUY2ULo3Rsgb88YDgCQ&usg=AFQjCNH070Hdr0xtql9x4TO7uupfE8O1cg&bvm=bv.41524429,d.Yms

Ponad to, aby zobaczyć zmianę "wyglądu" twojego okienka należy sztucznie wywołać komunikat WM_PAINT funkcją UpdateWindow, InvalidateRect lub czymś innym. Jest tego pełno w google, poszukaj. Możesz w swoim uchwycie kontekstu trzymać już nowy obraz, ale bez odświeżenia okna nie zostanie on narysowany.

W takim razie jak kiknąłeś przycisk (zakładamy, że jego ID to ID_BUTTON) powinieneś zrobić to mniejwięcej tak:
Globalnie

int promien = 0; 

Obsługa komunikatu WM_COMMAND: instrukcja switch(wParam)

 
case ID_BUTTON:
{
     //tutaj ustawiamy wartość liczbową promienia
     rysowac_promien = true;
     UpdateWindow(hwnd); // w tym momencie wywołuje się komunikat WM_PAINT i okno zostaje na nowo narysowane z twoim promieniem
     break;
}

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