Programming Windows

来源:互联网 发布:linux vim怎么用 编辑:程序博客网 时间:2024/05/16 04:54

Drawing Dots and Lines

x(t) = (1 - t)3 x0 + 3t (1 - t)2 x1 + 3t2 (1 - t) x2 + t3 x3

y(t) = (1 - t)3 y0 + 3t (1 - t)2 y1 + 3t2 (1 - t) y2 + t3 y3

Drawing Filled Areas

Alternate and Winding modes

At first, the difference between alternate and winding modes seems rather simple. For alternate mode, you can imagine a line drawn from a point in an enclosed area to infinity. The enclosed area is filled only if that imaginary line crosses an odd number of boundary lines. This is why the points of the star are filled but the center is not.

The example of the five-pointed star makes winding mode seem simpler than it actually is. When you're drawing a single polygon, in most cases winding mode will cause all enclosed areas to be filled. But there are exceptions.

To determine whether an enclosed area is filled in winding mode, you again imagine a line drawn from a point in that area to infinity. If the imaginary line crosses an odd number of boundary lines, the area is filled, just as in alternate mode. If the imaginary line crosses an even number of boundary lines, the area can either be filled or not filled. The area is filled if the number of boundary lines going in one direction (relative to the imaginary line) is not equal to the number of boundary lines going in the other direction. 

viewport & window

The GDI Mapping Mode

The viewport is specified in terms of device coordinates (pixels). Most often the viewport is the same as the client area, but it can also refer to whole-window coordinates or screen coordinates if you've obtained a device context from GetWindowDC or CreateDC. The point (0, 0) is the upper left corner of the client area (or the whole window or the screen). Values of x increase to the right, and values of y increase going down.

The window is specified in terms of logical coordinates, which might be pixels, millimeters, inches, or any other unit you want. You specify logical window coordinates in the GDI drawing functions.

keystroke

The six keystroke-message fields of the lParam variable:
31 30 29 28 27 26 25 24 23 ... 16 15 ... 00
31 : Transition State
30 : Previous Key State
29 : Context Code
24 : Extended Key Flag
16 - 23 : 8-Bit OEM Scan Code
00 - 15 : 16-Bit Repeat Count

WM_TIMER

void RotatePoint (POINT pt[], int iNum, int iAngle)
{
     int   i ;
     POINT ptTemp ;
    
     for (i = 0 ; i < iNum ; i++)
     {
          ptTemp.x = (int) (pt[i].x * cos (TWOPI * iAngle / 360) +
               pt[i].y * sin (TWOPI * iAngle / 360)) ;
         
          ptTemp.y = (int) (pt[i].y * cos (TWOPI * iAngle / 360) -
               pt[i].x * sin (TWOPI * iAngle / 360)) ;
         
          pt[i] = ptTemp ;
     }
}

Using the Timer for a Clock

x' = x * cos (a) + y * sin (a)

y' = y * cos (a) - x * sin (a)

CreateIC

// Invert the rectangle if the button is selected
if (pdis->itemState & ODS_SELECTED)
    InvertRect (pdis->hDC, &pdis->rcItem) ;

Resource
Icons, Cursors, Strings, and Custom ResourceshIcon = LoadIcon (hInstance, MAKEINTRESOURCE (125)) ;
The obscure method is this:
hIcon = LoadIcon (hInstance, TEXT ("#125")) ;
Windows recognizes the initial # character as prefacing a number in ASCII form.
ID numbers you use to add commands to the system menu must be lower than 0xF000
MapDialogRect
wndclass.cbWndExtra = DLGWINDOWEXTRA ; // Note!

Clipboard

GMEM_MOVEABLE flag allows Windows to move a memory block in virtual memory. This doesn't necessarily mean that the memory block will be moved in physical memory, but the address that the application uses to read and write to the block can change. Like the relation between Handle & Pointer
OpenClipboard (hwnd) ;
EmptyClipboard () ;
SetClipboardData (CF_TEXT, hGlobalText) ;
SetClipboardData (CF_BITMAP, hBitmap) ;
SetClipboardData (CF_METAFILEPICT, hGlobalMFP) ;
CloseClipboard () ;
Delayed Rendering
After you call SetClipboardData, don't continue to use the memory block. It no longer belongs to your program, and you should treat the handle as invalid.
Delayed Rendering
OpenClipboard (hwnd) ;
EmptyClipboard () ;
SetClipboardData (iFormat, NULL) ;
CloseClipboard () ;

WM_RENDERFORMAT, WM_RENDERALLFORMATS ( used when terminate), and WM_DESTROYCLIPBOARD
case WM_RENDERALLFORMATS :
     OpenClipboard (hwnd) ;
     EmptyClipboard () ;
                              // fall through
case WM_RENDERFORMAT :
     [put text into global memory block]
     SetClipboardData (CF_TEXT, hGlobal) ;

     if (message == WM_RENDERALLFORMATS)
          CloseClipboard () ;
     return 0 ;
delayed rendering must process three messages in its window procedure: WM_RENDERFORMAT, WM_RENDERALLFORMATS, and WM_DESTROYCLIPBOARD. Windows sends your window procedure a WM_RENDERFORMAT message when another program calls GetClipboardData. The value of wParam is the format requested. When you process the WM_RENDERFORMAT message, don't open and empty the clipboard. Simply create a global memory block for the format given by wParam, transfer the data to it, and call SetClipboardData with the correct format and the global handle. Obviously, you'll need to retain information in your program to construct this data properly when processing WM_RENDERFORMAT. When another program calls EmptyClipboard, Windows sends your program a WM_DESTROYCLIPBOARD message. This tells you that the information to construct the clipboard data is no longer needed. You are no longer the clipboard owner.  WM_RENDERALLFORMATS message is one of the last messages your window procedure receives
Private Data Formats
The easiest involves data that is ostensibly in one of the standard clipboard formats (that is, text, bitmap, or metafile)
The second way to use private formats involves the CF_OWNERDISPLAY flag.
The third way to use private clipboard data formats is to register your own clipboard format name.
WM_DRAWCLIPBOARD and WM_PAINTCLIPBOARD messages. The WM_PAINTCLIPBOARD message is sent by a clipboard viewer to programs that use the CF_OWNERDISPLAY clipboard format. The WM_ DRAWCLIPBOARD message is sent by Windows to the current clipboard viewer
ChangeClipboardChain (hwnd, hwndNextViewer) ;

PATPAINT
The PATPAINT raster operation involves a more complex operation. The result is equal to a bitwise OR operation between the pattern, the destination, and the inverse of the source.
The 15 ROP codes that have names are shown here.

Pattern (P):1 1 1 1 0 0 0 0


Source (S): 1 1 0 0 1 1 0 0


Destination (D):1 0 1 0 1 0 1 0Boolean OperationROP CodeNameResult:0 0 0 0 0 0 0 000x000042BLACKNESS
0 0 0 1 0 0 0 1~ (S ¦ D)0x1100A6NOTSRCERASE
0 0 1 1 0 0 1 1~S0x330008NOTSRCCOPY
0 1 0 0 0 1 0 0S & ~D0x440328SRCERASE
0 1 0 1 0 1 0 1~D0x550009DSTINVERT
0 1 0 1 1 0 1 0P ^ D0x5A0049PATINVERT
0 1 1 0 0 1 1 0S ^ D0x660046SRCINVERT
1 0 0 0 1 0 0 0S & D0x8800C6SRCAND
1 0 1 1 1 0 1 1~S ¦ D0xBB0226MERGEPAINT
1 1 0 0 0 0 0 0P & S0xC000CAMERGECOPY
1 1 0 0 1 1 0 0S0xCC0020SRCCOPY
1 1 1 0 1 1 1 0S ¦ D0xEE0086SRCPAINT
1 1 1 1 0 0 0 0P0xF00021PATCOPY
1 1 1 1 1 0 1 1P ¦ ~S ¦ D0xFB0A09PATPAINT
1 1 1 1 1 1 1 110xFF0062WHITENESS

PatBlt
Besides BitBlt and StretchBlt, Windows also includes a function called PatBlt ("pattern block transfer"). This is the simplest of the three "blt" functions. Unlike BitBlt and StretchBlt, it uses only a destination device context.

Pattern (P):1 1 0 0


Destination (D):1 0 1 0 Boolean OperationROP CodeNameResult:0 0 0 000x000042BLACKNESS
0 0 0 1~(P ¦ D)0x0500A9

0 0 1 0~P & D0x0A0329

0 0 1 1~P0x0F0001

0 1 0 0P & ~D0x500325

0 1 0 1~D0x550009DSTINVERT
0 1 1 0P ^ D0x5A0049PATINVERT
0 1 1 1~(P & D)0x5F00E9

1 0 0 0P & D0xA000C9

1 0 0 1~(P ^ D)0xA50065

1 0 1 0D0xAA0029

1 0 1 1~P ¦ D0xAF0229

1 1 0 0P 0xF00021PATCOPY
1 1 0 1P ¦ ~D0xF50225

1 1 1 0P ¦ D0xFA0089

1 1 1 110xFF0062WHITENESS

DDB
iWidthBytes = (cx * cBitsPixel + 15) & ~15) >> 3 ;