Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Du kan använda en pensel för att måla det inre av praktiskt taget vilken form som helst med hjälp av en GDI-funktion (grafikenhetsgränssnitt). Detta inkluderar inredningen av rektanglar, ellipser, polygoner och vägar. Beroende på kraven för ditt program kan du använda en fast borste av en angiven färg, en lagerborste, en luckborste eller en mönsterborste.
Det här avsnittet innehåller kodexempel som visar hur du skapar en anpassad penseldialogruta. Dialogrutan innehåller ett rutnät som representerar den bitmapp som systemet använder som pensel. En användare kan använda det här rutnätet för att skapa en bitmapp med mönsterborstar och sedan visa det anpassade mönstret genom att klicka på knappen Testmönster.
Följande bild visar ett mönster som skapats med hjälp av dialogrutan anpassad pensel.
Om du vill visa en dialogruta måste du först skapa en dialogrutemall. Följande dialogrutemall definierar dialogrutan för anpassad pensel .
CustBrush DIALOG 6, 18, 160, 118
STYLE WS_DLGFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "Custom Brush"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "", IDD_GRID, "Static", SS_BLACKFRAME |
WS_CHILD, 3, 2, 83, 79
CONTROL "", IDD_RECT, "Static", SS_BLACKFRAME |
WS_CHILD, 96, 11, 57, 28
PUSHBUTTON "Test Pattern", IDD_PAINTRECT, 96, 47, 57, 14
PUSHBUTTON "OK", IDD_OK, 29, 98, 40, 14
PUSHBUTTON "Cancel", IDD_CANCEL, 92, 98, 40, 14
END
Dialogrutan anpassad pensel innehåller fem kontroller: ett bitmappsrutnät, ett mönstervisningsfönster och tre knappar, märkta Testmönster, OKoch Avbryt. Med testmönster push-knappen kan användaren visa mönstret. Dialogrutans mall anger de övergripande dimensionerna i dialogrutefönstret, tilldelar ett värde till varje kontroll, anger platsen för varje kontroll och så vidare. Mer information finns i dialogrutor.
Kontrollvärdena i dialogrutemallen är konstanter som har definierats enligt följande i programmets huvudfil.
#define IDD_GRID 120
#define IDD_RECT 121
#define IDD_PAINTRECT 122
#define IDD_OK 123
#define IDD_CANCEL 124
När du har skapat en dialogrutemall och lagt till den i programmets resursdefinitionsfil måste du skriva en dialogprocedur. Den här proceduren bearbetar meddelanden som systemet skickar till dialogrutan. Följande utdrag från ett programs källkod visar dialogruteproceduren för dialogrutan anpassad pensel och de två programdefinierade funktioner som anropas.
BOOL CALLBACK BrushDlgProc( HWND hdlg, UINT message, LONG wParam,
LONG lParam)
{
static HWND hwndGrid; // grid-window control
static HWND hwndBrush; // pattern-brush control
static RECT rctGrid; // grid-window rectangle
static RECT rctBrush; // pattern-brush rectangle
static UINT bBrushBits[8]; // bitmap bits
static RECT rect[64]; // grid-cell array
static HBITMAP hbm; // bitmap handle
HBRUSH hbrush; // current brush
HBRUSH hbrushOld; // default brush
HRGN hrgnCell; // test-region handle
HDC hdc; // device context (DC) handle
int x, y, deltaX, deltaY; // drawing coordinates
POINTS ptlHit; // mouse coordinates
int i; // count variable
switch (message)
{
case WM_INITDIALOG:
// Retrieve a window handle for the grid-window and
// pattern-brush controls.
hwndGrid = GetDlgItem(hdlg, IDD_GRID);
hwndBrush = GetDlgItem(hdlg, IDD_RECT);
// Initialize the array of bits that defines the
// custom brush pattern with the value 1 to produce a
// solid white brush.
for (i=0; i<8; i++)
bBrushBits[i] = 0xFF;
// Retrieve dimensions for the grid-window and pattern-
// brush controls.
GetClientRect(hwndGrid, &rctGrid);
GetClientRect(hwndBrush, &rctBrush);
// Determine the width and height of a single cell.
deltaX = (rctGrid.right - rctGrid.left)/8;
deltaY = (rctGrid.bottom - rctGrid.top)/8;
// Initialize the array of cell rectangles.
for (y=rctGrid.top, i=0; y < rctGrid.bottom; y += deltaY)
{
for(x=rctGrid.left; x < (rctGrid.right - 8) && i < 64;
x += deltaX, i++)
{
rect[i].left = x; rect[i].top = y;
rect[i].right = x + deltaX;
rect[i].bottom = y + deltaY;
}
}
return FALSE;
case WM_PAINT:
// Draw the grid.
hdc = GetDC(hwndGrid);
for (i=rctGrid.left; i<rctGrid.right;
i+=(rctGrid.right - rctGrid.left)/8)
{
MoveToEx(hdc, i, rctGrid.top, NULL);
LineTo(hdc, i, rctGrid.bottom);
}
for (i=rctGrid.top; i<rctGrid.bottom;
i+=(rctGrid.bottom - rctGrid.top)/8)
{
MoveToEx(hdc, rctGrid.left, i, NULL);
LineTo(hdc, rctGrid.right, i);
}
ReleaseDC(hwndGrid, hdc);
return FALSE;
case WM_LBUTTONDOWN:
// Store the mouse coordinates in a POINT structure.
ptlHit = MAKEPOINTS((POINTS FAR *)lParam);
// Create a rectangular region with dimensions and
// coordinates that correspond to those of the grid
// window.
hrgnCell = CreateRectRgn(rctGrid.left, rctGrid.top,
rctGrid.right, rctGrid.bottom);
// Retrieve a window DC for the grid window.
hdc = GetDC(hwndGrid);
// Select the region into the DC.
SelectObject(hdc, hrgnCell);
// Test for a button click in the grid-window rectangle.
if (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y))
{
// A button click occurred in the grid-window
// rectangle; isolate the cell in which it occurred.
for(i=0; i<64; i++)
{
DeleteObject(hrgnCell);
hrgnCell = CreateRectRgn(rect[i].left,
rect[i].top,
rect[i].right, rect[i].bottom);
if (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y))
{
InvertRgn(hdc, hrgnCell);
// Set the appropriate brush bits.
if (i % 8 == 0)
bBrushBits[i/8] = bBrushBits[i/8] ^ 0x80;
else if (i % 8 == 1)
bBrushBits[i/8] = bBrushBits[i/8] ^ 0x40;
else if (i % 8 == 2)
bBrushBits[i/8] = bBrushBits[i/8] ^ 0x20;
else if (i % 8 == 3)
bBrushBits[i/8] = bBrushBits[i/8] ^ 0x10;
else if (i % 8 == 4)
bBrushBits[i/8] = bBrushBits[i/8] ^ 0x08;
else if (i % 8 == 5)
bBrushBits[i/8] = bBrushBits[i/8] ^ 0x04;
else if (i % 8 == 6)
bBrushBits[i/8] = bBrushBits[i/8] ^ 0x02;
else if (i % 8 == 7)
bBrushBits[i/8] = bBrushBits[i/8] ^ 0x01;
// Exit the "for" loop after the bit is set.
break;
} // end if
} // end for
} // end if
// Release the DC for the control.
ReleaseDC(hwndGrid, hdc);
return TRUE;
case WM_COMMAND:
switch (wParam)
{
case IDD_PAINTRECT:
hdc = GetDC(hwndBrush);
// Create a monochrome bitmap.
hbm = CreateBitmap(8, 8, 1, 1,
(LPBYTE)bBrushBits);
// Select the custom brush into the DC.
hbrush = CreatePatternBrush(hbm);
hbrushOld = SelectObject(hdc, hbrush);
// Use the custom brush to fill the rectangle.
Rectangle(hdc, rctBrush.left, rctBrush.top,
rctBrush.right, rctBrush.bottom);
// Clean up memory.
SelectObject(hdc, hbrushOld);
DeleteObject(hbrush);
DeleteObject(hbm);
ReleaseDC(hwndBrush, hdc);
return TRUE;
case IDD_OK:
case IDD_CANCEL:
EndDialog(hdlg, TRUE);
return TRUE;
} // end switch
break;
default:
return FALSE;
}
}
int GetStrLngth(LPTSTR cArray)
{
int i = 0;
while (cArray[i++] != 0);
return i-1;
}
DWORD RetrieveWidth(LPTSTR cArray, int iLength)
{
int i, iTmp;
double dVal, dCount;
dVal = 0.0;
dCount = (double)(iLength-1);
for (i=0; i<iLength; i++)
{
iTmp = cArray[i] - 0x30;
dVal = dVal + (((double)iTmp) * pow(10.0, dCount--));
}
return (DWORD)dVal;
}
Proceduren för dialogrutan Anpassad Pensel bearbetar fyra meddelanden, som beskrivs i följande tabell.
| Meddelande | Handling |
|---|---|
| WM_INITDIALOG | Hämtar ett fönsterhandtag och dimensioner för kontrollerna grid-window och pattern-brush, beräknar dimensionerna för en enskild cell i rutnätsfönstrets kontroll och initierar en matris med rutnätscellkoordinater. |
| WM_PAINT | Ritar rutnätsmönstret i kontrollen för rutnätsfönstret. |
| WM_LBUTTONDOWN | Avgör om markören finns i rutnätsfönstrets kontroll när användaren trycker på den vänstra musknappen. I så fall inverteras lämplig rutnätscell i dialogrutan och cellens tillstånd registreras i en matris med bitar som används för att skapa bitmappen för den anpassade penseln. |
| WM_COMMAND | Bearbetar indata för de tre knappkontrollerna. Om användaren klickar på knappen Testmönster målar dialogrutan kontrollen Testmönster med det nya anpassade penselmönstret. Om användaren klickar på knappen OK eller Avbryt utför dialogrutan åtgärder i enlighet med detta. |
Mer information om meddelanden och meddelandebearbetning finns i Meddelanden och meddelandeköer.
När du har skrivit dialogrutan tar du med funktionsdefinitionen för proceduren i programmets huvudfil och anropar sedan dialogruteproceduren vid lämplig plats i programmet.
Följande utdrag från programmets huvudfil visar funktionsdefinitionen för dialogruteproceduren och de två funktioner som anropas.
BOOL CALLBACK BrushDlgProc(HWND, UINT, WPARAM, LPARAM);
int GetStrLngth(LPTSTR);
DWORD RetrieveWidth(LPTSTR, int);
Slutligen visar följande kod hur dialogruteproceduren anropas från programmets källkodsfil.
DialogBox((HANDLE)GetModuleHandle(NULL),
(LPTSTR)"CustBrush",
hWnd,
(DLGPROC) BrushDlgProc);
Det här anropet görs vanligtvis som svar på att användaren väljer ett alternativ från programmets meny.