Delen via


Borstels gebruiken

U kunt een kwast gebruiken om het interieur van vrijwel elke vorm te schilderen met behulp van een GDI-functie (Graphics Device Interface). Dit omvat de binnenkanten van rechthoeken, ellipsen, veelhoeken en paden. Afhankelijk van de vereisten van uw toepassing kunt u een effen borstel van een opgegeven kleur, een voorraadborstel, een luikborstel of een patroonborstel gebruiken.

Deze gedeelte bevat codevoorbeelden die het maken van een aangepast penseldialoogvenster laten zien. Het dialoogvenster bevat een raster dat de bitmap vertegenwoordigt die het systeem als penseel gebruikt. Een gebruiker kan dit raster gebruiken om een patroonborstelafbeelding te maken en vervolgens het aangepaste patroon weer te geven door te klikken op de knop Testpatroon.

In de volgende afbeelding ziet u een patroon dat is gemaakt met behulp van het dialoogvenster Aangepaste kwast.

schermafbeelding van het aangepaste kwast dialoogvenster

Als u een dialoogvenster wilt weergeven, moet u eerst een dialoogvenstersjabloon maken. Met de volgende dialoogvenstersjabloon wordt het dialoogvenster Aangepaste kwast gedefinieerd.

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 

Het dialoogvenster Aangepaste kwast bevat vijf besturingselementen: een bitmap-rooster venster, een venster voor patroonweergave en drie drukknoppen met de labels Testpatroon, OKen Annuleren. Met de testpatroon drukknop kan de gebruiker het patroon bekijken. De dialoogvenstersjabloon geeft de algemene dimensies van het dialoogvenstervenster, wijst een waarde toe aan elk besturingselement, geeft de locatie van elk besturingselement, enzovoort. Zie dialoogvenstersvoor meer informatie.

De besturingswaarden in de dialoogvenstersjabloon zijn constanten die als volgt zijn gedefinieerd in het headerbestand van de toepassing.

#define IDD_GRID      120 
#define IDD_RECT      121 
#define IDD_PAINTRECT 122 
#define IDD_OK        123 
#define IDD_CANCEL    124 

Nadat u een dialoogvenstersjabloon hebt gemaakt en deze hebt opgenomen in het resourcedefinitiebestand van de toepassing, moet u een dialoogvensterprocedure schrijven. Met deze procedure worden berichten verwerkt die het systeem naar het dialoogvenster verzendt. In het volgende fragment van de broncode van een toepassing ziet u de dialoogvensterprocedure voor het dialoogvenster Aangepaste kwast en de twee door de toepassing gedefinieerde functies die worden aanroepen.

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; 
} 

De dialoogvensterprocedure voor het dialoogvenster Aangepaste kwast verwerkt vier berichten, zoals beschreven in de volgende tabel.

Bericht Actie
WM_INITDIALOG Hiermee haalt u een venstergreep en dimensies op voor de besturingselementen voor rastervensters en patroonborstels, berekent u de afmetingen van één cel in het rastervensterbesturingselement en initialiseert u een matrix met rastercelcoördinaten.
WM_PAINT Hiermee teken je het rasterpatroon in de rastervenstercontrole.
WM_LBUTTONDOWN Bepaalt of de cursor zich in het rastervensterbesturing bevindt wanneer de gebruiker op linkermuisknop drukt. Als dit het geval is, wordt met de dialoogvensterprocedure de juiste rastercel omgekeerd en wordt de status van die cel vastgelegd in een matrix met bits die wordt gebruikt om de bitmap voor de aangepaste kwast te maken.
WM_COMMAND Verwerkt invoer voor de drie drukknoppen. Als de gebruiker op de knop Testpatroon klikt, wordt in het dialoogvenster het besturingselement Testpatroon met het nieuwe aangepaste kwastpatroon weergegeven. Als de gebruiker op de knop OK of Annuleren klikt, voert de procedure in het dialoogvenster acties dienovereenkomstig uit.

 

Voor meer informatie over berichten en de verwerking van berichten, zie berichten en berichtenwachtrijen.

Nadat u de dialoogvensterprocedure hebt geschreven, neemt u de functiedefinitie voor de procedure op in het headerbestand van de toepassing en roept u vervolgens de dialoogvensterprocedure aan op het juiste punt in de toepassing.

In het volgende fragment uit het headerbestand van de toepassing ziet u de functiedefinitie voor de dialoogvensterprocedure en de twee functies die worden aangeroepen.

BOOL CALLBACK BrushDlgProc(HWND, UINT, WPARAM, LPARAM); 
int GetStrLngth(LPTSTR); 
DWORD RetrieveWidth(LPTSTR, int); 

Ten slotte laat de volgende code zien hoe de dialoogvensterprocedure wordt aangeroepen vanuit het broncodebestand van de toepassing.

    DialogBox((HANDLE)GetModuleHandle(NULL), 
        (LPTSTR)"CustBrush", 
        hWnd, 
        (DLGPROC) BrushDlgProc); 

Deze aanroep wordt meestal uitgevoerd als reactie op de gebruiker die een optie kiest in het menu van de toepassing.