Well jeg har intet imod at sende dig koden, Bertel... Jeg er bare ikke glad for at offentliggøre den.
Forresten, skal jeg også kalde DeleteObject på strukturer som RECT?
Her er koden til GDI-eksemplet:
#include <windows.h>
#include <vector>
std::vector<RECT> Squares;
void _Rectangle(HDC hdc, RECT sq)
{
SelectObject(hdc, CreatePen(PS_SOLID, 2, RGB(142, 198, 254)));
// Draw from left, top to bottom, top
MoveToEx(hdc, sq.left, sq.top, NULL);
LineTo (hdc, sq.left, sq.bottom);
// Draw from left, top to right, top
MoveToEx(hdc, sq.left, sq.top, NULL);
LineTo (hdc, sq.right, sq.top);
// Draw from right, top to right, bottom
MoveToEx(hdc, sq.right, sq.top, NULL);
LineTo (hdc, sq.right, sq.bottom);
// Draw from left, bottom to right, bottom
MoveToEx(hdc, sq.left, sq.bottom, NULL);
LineTo (hdc, sq.right, sq.bottom);
HDC mem = CreateCompatibleDC(hdc);
HBITMAP sqbg = LoadBitmap(GetModuleHandle(NULL), TEXT("IDB_SQBG"));
SelectObject(mem, sqbg);
StretchBlt (hdc, sq.left + 1, sq.top + 1, sq.right - sq.left - 2, sq.bottom - sq.top - 2, mem, 0, 0, 6, 601, SRCCOPY);
DeleteObject(sqbg);
DeleteDC(mem);
}
LRESULT __stdcall WinProc(HWND handle, unsigned int message, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;
static HDC mem;
static HBITMAP canvas;
static RECT rcSquare = { -1, -1, -1, -1 };
static RECT rcClient;
switch (message)
{
case WM_SIZE:
case WM_CREATE:
GetClientRect(handle, &rcClient);
return 0;
case WM_PAINT:
BeginPaint(handle, &ps);
mem = CreateCompatibleDC(ps.hdc);
canvas = CreateCompatibleBitmap(ps.hdc, rcClient.right, rcClient.bottom);
SelectObject(mem, canvas);
FillRect(mem, &rcClient, (HBRUSH)GetStockObject(WHITE_BRUSH));
// Draw squares
for (int i = 0; i < Squares.size(); i++)
{
_Rectangle(mem, Squares[i]);
}
BitBlt(ps.hdc, 0, 0, rcClient.right, rcClient.bottom, mem, 0, 0, SRCCOPY);
DeleteObject(canvas);
DeleteDC(mem);
EndPaint(handle, &ps);
return 0;
case WM_MOUSEMOVE:
if (!(wParam & MK_LBUTTON))
return 0;
if (rcSquare.left < 0)
{
rcSquare.left = LOWORD(lParam);
rcSquare.top = HIWORD(lParam);
return 0;
}
else
{
rcSquare.right = LOWORD(lParam);
rcSquare.bottom = HIWORD(lParam);
}
if (!Squares.size())
Squares.push_back(rcSquare);
else
{
Squares.erase(Squares.begin() + (Squares.size() - 1));
Squares.push_back(rcSquare);
}
InvalidateRect(handle, &rcClient, false);
return 0;
case WM_LBUTTONUP:
if (rcSquare.left >= 0)
{
Squares.push_back(rcSquare);
rcSquare.left = -1;
InvalidateRect(handle, &rcClient, false);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(handle, message, wParam, lParam);
}
int __stdcall WinMain(HINSTANCE, HINSTANCE, PSTR, int)
{
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = WinProc;
wc.lpszClassName = TEXT("GdiLagEks");
wc.lpszMenuName = NULL;
wc.style = 0;
RegisterClass(&wc);
HWND handle = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("GdiLagEks"), TEXT("Eksempel på \"GDI lag\""),
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
GetSystemMetrics(SM_CXSCREEN) / 2 - 400,
GetSystemMetrics(SM_CYSCREEN) / 2 - 300,
800, 600,
NULL, NULL, NULL, NULL);
ShowWindow(handle, SW_SHOW);
UpdateWindow(handle);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Nu har jeg ændret lidt i koden, og wow... Den tilføjer næsten ikke nogle GDI-objekter (kun en gang i mellem og ikke 1 per firkant, som det er tilfældet med Paint).
Koden ser nu således ud:
#include <windows.h>
#include <vector>
std::vector<RECT> Squares;
void _Rectangle(HDC hdc, RECT sq)
{
HBITMAP sqbg = LoadBitmap(GetModuleHandle(NULL), TEXT("IDB_SQBG"));
HPEN border = CreatePen(PS_SOLID, 2, RGB(142, 198, 254));
SelectObject(hdc, border);
// Draw from left, top to bottom, top
MoveToEx(hdc, sq.left, sq.top, NULL);
LineTo (hdc, sq.left, sq.bottom);
// Draw from left, top to right, top
MoveToEx(hdc, sq.left, sq.top, NULL);
LineTo (hdc, sq.right, sq.top);
// Draw from right, top to right, bottom
MoveToEx(hdc, sq.right, sq.top, NULL);
LineTo (hdc, sq.right, sq.bottom);
// Draw from left, bottom to right, bottom
MoveToEx(hdc, sq.left, sq.bottom, NULL);
LineTo (hdc, sq.right, sq.bottom);
HDC mem = CreateCompatibleDC(hdc);
SelectObject(mem, sqbg);
StretchBlt (hdc, sq.left + 1, sq.top + 1, sq.right - sq.left - 2, sq.bottom - sq.top - 2, mem, 0, 0, 6, 601, SRCCOPY);
DeleteObject(border);
DeleteObject(sqbg);
DeleteDC(mem);
}
LRESULT __stdcall WinProc(HWND handle, unsigned int message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC mem;
HBITMAP canvas;
HBRUSH hbrBack = (HBRUSH)GetStockObject(WHITE_BRUSH);
static RECT rcSquare = { -1, -1, -1, -1 };
static RECT rcClient;
switch (message)
{
case WM_SIZE:
case WM_CREATE:
GetClientRect(handle, &rcClient);
return 0;
case WM_PAINT:
BeginPaint(handle, &ps);
mem = CreateCompatibleDC(ps.hdc);
canvas = CreateCompatibleBitmap(ps.hdc, rcClient.right, rcClient.bottom);
SelectObject(mem, canvas);
FillRect(mem, &rcClient, hbrBack);
// Draw squares
for (int i = 0; i < Squares.size(); i++)
{
_Rectangle(mem, Squares[i]);
}
BitBlt(ps.hdc, 0, 0, rcClient.right, rcClient.bottom, mem, 0, 0, SRCCOPY);
DeleteObject(canvas);
DeleteObject(hbrBack);
DeleteDC(mem);
EndPaint(handle, &ps);
DeleteObject(mem);
return 0;
case WM_MOUSEMOVE:
if (!(wParam & MK_LBUTTON))
return 0;
if (rcSquare.left < 0)
{
rcSquare.left = LOWORD(lParam);
rcSquare.top = HIWORD(lParam);
return 0;
}
else
{
rcSquare.right = LOWORD(lParam);
rcSquare.bottom = HIWORD(lParam);
}
if (!Squares.size())
Squares.push_back(rcSquare);
else
{
Squares.erase(Squares.begin() + (Squares.size() - 1));
Squares.push_back(rcSquare);
}
InvalidateRect(handle, &rcClient, false);
return 0;
case WM_LBUTTONUP:
if (rcSquare.left >= 0)
{
Squares.push_back(rcSquare);
rcSquare.left = -1;
InvalidateRect(handle, &rcClient, false);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(handle, message, wParam, lParam);
}
int __stdcall WinMain(HINSTANCE, HINSTANCE, PSTR, int)
{
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = WinProc;
wc.lpszClassName = TEXT("GdiLagEks");
wc.lpszMenuName = NULL;
wc.style = 0;
RegisterClass(&wc);
HWND handle = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("GdiLagEks"), TEXT("Eksempel på \"GDI lag\""),
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
GetSystemMetrics(SM_CXSCREEN) / 2 - 400,
GetSystemMetrics(SM_CYSCREEN) / 2 - 300,
800, 600,
NULL, NULL, NULL, NULL);
ShowWindow(handle, SW_SHOW);
UpdateWindow(handle);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Indlæg senest redigeret d. 15.04.2009 01:45 af Bruger #8985