WinAPI - rysowanie ala Paint

Odpowiedz Nowy wątek
2016-03-04 19:25
0

Mam tu problem z programem w WinAPI C++. Nie działa mi rysowanie myszą, coś ala Paint, tzn. że jak naduszę lewy przycisk myszy i będę go trzymał to będzie mi rysować. Niestety mi tu nie działa (w ogóle nie rysuje, nie wiem czemu).

FirstApp.h

https://onedrive.live.com/red[...]iFkbeiuA&ithint=folder%2c

Jakby się komuś nie chciało ściągać:

 #define MojaIkona 1

#define MyMenu 102

#define NewButton 90
#define OpenButton 91
#define SaveButton 92
#define SaveAsButton 93
#define UndoButton 94
#define CutButton 95
#define PasteButton 96
#define SettingsButton 97
#define PrintButton 98
#define EndButton 99
#define ID_COMBOBOX 500

BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM
    lParam)
{
    return TRUE;
}

FirstApp.rc

#include "FirstApp.h"

MojaIkona ICON "icon1.ico"

MyMenu MENU
BEGIN
    POPUP "&Plik"
    BEGIN
        MENUITEM "&Nowy", NewButton
        MENUITEM "&Otwórz", OpenButton
        MENUITEM "Zapisz", SaveButton
        MENUITEM "Zapisz jako", SaveAsButton
        MENUITEM SEPARATOR
        MENUITEM "Ustawienia strony",SettingsButton
        MENUITEM "Drukuj", PrintButton
        MENUITEM SEPARATOR
        MENUITEM "Zakon&cz", EndButton
    END
    POPUP "&Edycja"
    BEGIN
        MENUITEM "Cofnij", UndoButton,CHECKED
        MENUITEM SEPARATOR
        MENUITEM "Wytnij", CutButton
        MENUITEM "Wklej", PasteButton,GRAYED
    END
END

FirstApp.cpp

#include <Windows.h>
#include "FirstApp.h"

HINSTANCE hInst;

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HWND hWndButton;
    HWND hWndAbout;
    HDC hDC;

    bool LPM = false;

    switch (message)
    {
    case WM_CREATE:
        hWndButton = CreateWindow(TEXT("BUTTON"), TEXT("B1"), BS_FLAT | WS_VISIBLE |
            WS_CHILD, 10, 20, 50, 20, hwnd, (HMENU)210, hInst, NULL);
        break;
    case WM_PAINT:
        hDC = GetDC(hwnd);

        SelectObject(hDC, GetStockObject(ANSI_VAR_FONT));

        TextOut(hDC, 0, 0, TEXT("Text output to client area."), 27);

        ReleaseDC(hwnd, hDC);
        break;
    case WM_COMMAND:
        switch (wParam)
        {
        case EndButton:
            PostQuitMessage(0);
            break;
        case SaveButton:
            MessageBox(NULL, "Nie dziala jeszcze", "Lipa", MB_OK);
            break;
        case UndoButton:
        break;
        case 210:
            MessageBox(0, TEXT("Nacisnales przycisk"),
            TEXT("przycisk"), MB_OK);
        }
        break;
    case WM_LBUTTONDOWN:
        LPM = true;
        SendMessage(hwnd, WM_MOUSEMOVE, wParam, lParam);
        break;
    case WM_LBUTTONUP:
        LPM = false;
        break;
    case WM_MOUSEMOVE:
        if (LPM)
        {
            hDC = GetDC(hwnd);
            for (int i = 1; i <= 10; i++)
            {
                for (int j = 1; j <= 10; j++)
                    SetPixel(hDC, LOWORD(lParam) + i - 6, HIWORD(lParam) + j - 6, RGB(0, 0, 0));
            }
            ReleaseDC(hwnd, hDC);
        }
        break;

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

HWND hcombb;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE
    hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    WNDCLASS wc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(MojaIkona));
    wc.hCursor = LoadCursor(NULL,IDC_CROSS);
    wc.hbrBackground = HBRUSH(COLOR_WINDOW+1);
    wc.lpszMenuName = MAKEINTRESOURCE(MyMenu);
    wc.lpszClassName = TEXT("FirstAppClass");
    if (!RegisterClass(&wc))return (FALSE);

    HWND hWnd = CreateWindow(
        TEXT("FirstAppClass"),
        TEXT("Pierwsze Okno"),
        WS_OVERLAPPEDWINDOW,
        0,
        0,
        400,
        400,
        NULL,
        NULL,
        hInstance,
        NULL);

    if (hWnd == NULL) return (FALSE);

    ShowWindow(hWnd, iCmdShow);

    hcombb = CreateWindow("COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,
        10, 70, 100, 200, hWnd, HMENU(ID_COMBOBOX), hInstance, NULL);
    SendMessage(hcombb, CB_ADDSTRING, NULL, (LPARAM) "Element 1");
    SendMessage(hcombb, CB_ADDSTRING, NULL, (LPARAM) "Element 2");
    SendMessage(hcombb, CB_ADDSTRING, NULL, (LPARAM) "Element 3");
    SendMessage(hcombb, CB_ADDSTRING, NULL, (LPARAM) "Element 4");
    SendMessage(hcombb, CB_ADDSTRING, NULL, (LPARAM) "Element 5");
    SendMessage(hcombb, CB_ADDSTRING, NULL, (LPARAM) "Element 6");

    MSG msg;

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

    MessageBox(0, TEXT("Hejka"), TEXT("Informacja"), MB_OK);
    return 0;
} 
edytowany 3x, ostatnio: Mikilll, 2016-03-04 21:10
wstaw na gihuba czy gdziekolwiek, gdzie nie trzeba ściągać, żeby zobaczyć kod - stryku 2016-03-04 19:30

Pozostało 580 znaków

2016-03-04 19:43
1

wywal binarki - exe i obj, wywal sdf i resztę spakuj do zipa. nie powinien zajmować więcej niż 100 kB.

edytowany 1x, ostatnio: Azarien, 2016-03-04 19:44
Zrobione (waży 600 kB) - Mikilll 2016-03-04 20:34

Pozostało 580 znaków

2016-03-04 23:17

Mogłeś jeszcze wywalić całe katalogi Debug, Podstawowa aplikacja WinApi\Debug i .vs i się zrobi 11 kilo.
Plik RCa08612 to też jakiś śmieć.

case EndButton:
PostQuitMessage(0);

Daj tu PostMessage(hwnd, WM_CLOSE, 0, 0);. Tak należy zamykać okno. W ten sposób zachowana będzie prawidłowa sekwencja komunikatów WM_CLOSE i WM_DESTROY.

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

To powinno być pod default: w switchu, a poniżej switcha return 0.

hcombb = CreateWindow("COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,
10, 70, 100, 200, hWnd, HMENU(ID_COMBOBOX), hInstance, NULL);

Buttona tworzysz w WM_CREATE a combo w WinMain. Brak konsekwencji.

case WM_LBUTTONDOWN:
LPM = true;
SendMessage(hwnd, WM_MOUSEMOVE, wParam, lParam);

MOUSEMOVE to nie LBUTTONDOWN. Powinna ci się czerwona lampka zapalić że robisz jakiś brzydki hack.
No i tu mamy sedno sprawy: LPM to zmienna lokalna. Wychodzisz z funkcji WndProc, kolejny komunikat to jej nowe wywołanie i LPM jest znowu false.

Całość wygląda jak Windows 3.11 bo nie ustawiasz systemowego fontu ani nie masz manifestu, ale to drugorzędne sprawy.

Manifest "common controls" najłatwiej zrobić w ten sposób:

#include <commctrl.h>
#pragma comment (lib, "comctl32.lib")
#pragma comment(linker,"\"/manifestdependency:type='Win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

i dodaj InitCommonControls(); na początku WinMain.

Zostaje kwestia fontu. Robisz coś takiego:

// zmienna globalna
HFONT hfont;
//WinMain
    InitCommonControls();

    LOGFONT lf = {};
    strcpy_s(lf.lfFaceName, "Segoe UI");
    lf.lfHeight = -12;
    hfont = CreateFontIndirect(&lf);

i teraz po każdym CreateWindow dodajesz

SendMessage(okno, WM_SETFONT, (WPARAM) hfont, 0);

tak dla okna głównego i dla każdej kontrolki.

jeszcze napis możesz poprawić:

SelectObject(hDC, hfont); // zamiast ANSI_VAR_FONT

i zaczyna to wyglądać.

edytowany 2x, ostatnio: Azarien, 2016-03-04 23:31
Dzięki. A odnośnie tej czcionki to napisałem tak jak ty i czcionka jest dalej ta sama. Nie widzę też różnicy między Windowsem 3.11 (po ustawieniu manifestu), a tym nowszym co pisałeś. - Mikilll 2016-03-05 12:46
źle robisz albo słabo patrzysz. - Azarien 2016-03-05 12:48
Dobra. Już wszystko działa :) - Mikilll 2016-03-05 12:50

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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