WinAPI - rysowanie ala Paint

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/redir?resid=83A18B9482AD69AE!1961&authkey=!AJUIPQViFkbeiuA&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;
} 
1

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

2

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ć.

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