void WinInitPicture (int size, int mode, int pr, int pg, int pb, int br, int bg, int bb, char *fname, int fstyle, int fsize, HRGN clipRgn, BOOL bDoubleBuffered, OSPictContext context ) { LOGBRUSH lb; LOGFONT lf; DWORD style; context->penSize = size; context->penPat = iBlackPattern; context->penMode = mode; context->penColor = RGB (pr, pg, pb); context->backColor = RGB (br, bg, bb); context->lastActivity = FILLING; if (bDoubleBuffered) { RECT clipRect; if (GetClipBox(context->hDC,&clipRect) == ERROR) { printf("osInitPicture -> GetClipBox failed\n"); exit(1); } context->hBufferedDC = context->hDC; context->hDC = CreateCompatibleDC(context->hBufferedDC); context->hBufferBitmap = CreateCompatibleBitmap(context->hBufferedDC,clipRect.right-clipRect.left,clipRect.bottom-clipRect.top); SelectObject(context->hDC, context->hBufferBitmap); if (!BitBlt(context->hDC, 0, 0, clipRect.right-clipRect.left, clipRect.bottom-clipRect.top, context->hBufferedDC, clipRect.left, clipRect.top, SRCCOPY)) { printf("osDonePicture -> BitBlt failed\n"); exit(1); } SetViewportOrgEx(context->hDC,-clipRect.left,-clipRect.top,NULL); } thePolygon = NULL; SetPolyFillMode (context->hDC, WINDING); strcpy (context->curFont, fname); context->fontstyle = fstyle; context->fontsize = PointsToPix(context->hDC,fsize); // PointsToPix by MW SetLogFontData (&lf, context->curFont, context->fontstyle, context->fontsize); if (context->penSize == 1) style = PS_COSMETIC | PS_SOLID; else style = PS_GEOMETRIC | PS_INSIDEFRAME; lb.lbStyle = BS_SOLID; lb.lbColor = context->penColor; lb.lbHatch = 0; context->theNormalPen = ExtCreatePen (style, context->penSize, &lb, 0, NULL); lb.lbStyle = BS_SOLID; lb.lbColor = context->backColor; lb.lbHatch = 0; context->theBackPen = ExtCreatePen (style, context->penSize, &lb, 0, NULL); SetBrushOrgEx (context->hDC,0,0,NULL); context->theNormalBrush = CreateSolidBrush (context->penColor); context->theBackBrush = CreateSolidBrush (context->backColor); context->theFont = CreateFontIndirect (&lf); SaveDC (context->hDC); SetWindowOrgEx (context->hDC, 0,0, NULL); SelectObject (context->hDC, GetStockObject (NULL_PEN)); SelectObject (context->hDC, context->theNormalBrush); SelectObject (context->hDC, context->theFont); SetBkMode (context->hDC, TRANSPARENT); SetBkColor (context->hDC, context->backColor); SetTextAlign (context->hDC, TA_LEFT | TA_BASELINE); WinSetMode (context->penMode, context); SetStretchBltMode (context->hDC,COLORONCOLOR); /* PA: when stretching bitmaps, use COLORONCOLOR mode. */ if (ghCaretWnd) { int mess, p1, p2, p3, p4, p5, p6; WinKickOsThread (CcRqHIDECARET, (int) ghCaretWnd, 0, 0, 0, 0, 0, &mess, &p1, &p2, &p3, &p4, &p5, &p6); } if (clipRgn != NULL) SelectClipRgn (context->hDC, clipRgn); } /* WinInitPicture */
//--------------------------------------------------------------------------// //--------------------------------------------------------------------------// LRESULT CCtlPanel::OnDrawItem(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { UINT idCtl = wParam; LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam; if (idCtl == IDC_COLOR) { CAGDC dc(lpdis->hDC); HBRUSH hbr = (HBRUSH) GetStockObject(WHITE_BRUSH); FillRect(lpdis->hDC, &lpdis->rcItem, hbr); if ((int) lpdis->itemID != -1) { COLORREF clr = (COLORREF) ::SendMessage(lpdis->hwndItem, CB_GETITEMDATA, lpdis->itemID, 0); RECT rect = lpdis->rcItem; InflateRect(&rect, -4, -2); hbr = CreateSolidBrush(clr | PALETTERGB_FLAG); FillRect(lpdis->hDC, &rect, hbr); DeleteObject(hbr); hbr = (HBRUSH) GetStockObject(BLACK_BRUSH); FrameRect(lpdis->hDC, &rect, hbr); } if (lpdis->itemState & ODS_FOCUS || lpdis->itemState & ODS_SELECTED) { hbr = (HBRUSH) GetStockObject(BLACK_BRUSH); FrameRect(lpdis->hDC, &lpdis->rcItem, hbr); } } else if (idCtl == IDC_FONT) { if ((int) lpdis->itemID != -1) { int nFont = ::SendMessage(lpdis->hwndItem, CB_GETITEMDATA, lpdis->itemID, 0); FONTARRAY &FontArray = GetFontArray(); LOGFONT NewFont = FontArray[nFont].lf; NewFont.lfHeight = m_nFontHeight; NewFont.lfWidth = 0; if (NewFont.lfCharSet == SYMBOL_CHARSET) { lstrcpy(NewFont.lfFaceName, "Arial"); NewFont.lfCharSet = ANSI_CHARSET; NewFont.lfPitchAndFamily = FF_SWISS; } SaveDC(lpdis->hDC); SetTextAlign(lpdis->hDC, TA_LEFT | TA_TOP | TA_NOUPDATECP); if (lpdis->itemState & ODS_SELECTED) SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); else SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT)); if (lpdis->itemState & ODS_SELECTED) SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); else SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW)); HFONT hFont = CreateFontIndirect(&NewFont); HFONT hOldFont = (HFONT) SelectObject(lpdis->hDC, hFont); ExtTextOut(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, ETO_CLIPPED | ETO_OPAQUE, &lpdis->rcItem, FontArray[nFont].szFullName, lstrlen(FontArray[nFont].szFullName), NULL); if (lpdis->itemState & ODS_FOCUS) DrawFocusRect(lpdis->hDC, &lpdis->rcItem); SelectObject(lpdis->hDC, hOldFont); DeleteObject(hFont); RestoreDC(lpdis->hDC, -1); } } bHandled = TRUE; return (TRUE); }
void GraphicsContextPlatformPrivate::save() { if (!m_hdc) return; SaveDC(m_hdc); }
static void surface_begin(XSurface *surf) { surf->save = SaveDC(surf->hdc); SelectObject(surf->hdc, surf->bitmap); }
bool gfxUniscribeShaper::ShapeText(gfxContext *aContext, const char16_t *aText, uint32_t aOffset, uint32_t aLength, int32_t aScript, gfxShapedText *aShapedText) { DCFromContext aDC(aContext); bool result = true; HRESULT rv; Uniscribe us(aText, aShapedText, aOffset, aLength); /* itemize the string */ int numItems = us.Itemize(); uint32_t length = aLength; SaveDC(aDC); uint32_t ivs = 0; for (int i = 0; i < numItems; ++i) { int iCharPos = us.ScriptItem(i)->iCharPos; int iCharPosNext = us.ScriptItem(i+1)->iCharPos; if (ivs) { iCharPos += 2; if (iCharPos >= iCharPosNext) { ivs = 0; continue; } } if (i+1 < numItems && iCharPosNext <= length - 2 && aText[iCharPosNext] == H_SURROGATE(kUnicodeVS17) && uint32_t(aText[iCharPosNext + 1]) - L_SURROGATE(kUnicodeVS17) <= L_SURROGATE(kUnicodeVS256) - L_SURROGATE(kUnicodeVS17)) { ivs = SURROGATE_TO_UCS4(aText[iCharPosNext], aText[iCharPosNext + 1]); } else { ivs = 0; } UniscribeItem item(aContext, aDC, this, aText + iCharPos, iCharPosNext - iCharPos, us.ScriptItem(i), ivs); if (!item.AllocateBuffers()) { result = false; break; } if (!item.ShapingEnabled()) { item.EnableShaping(); } rv = item.Shape(); if (FAILED(rv)) { // we know we have the glyphs to display this font already // so Uniscribe just doesn't know how to shape the script. // Render the glyphs without shaping. item.DisableShaping(); rv = item.Shape(); } #ifdef DEBUG if (FAILED(rv)) { NS_WARNING("Uniscribe failed to shape with font"); } #endif if (SUCCEEDED(rv)) { rv = item.Place(); #ifdef DEBUG if (FAILED(rv)) { // crap fonts may fail when placing (e.g. funky free fonts) NS_WARNING("Uniscribe failed to place with font"); } #endif } if (FAILED(rv)) { // Uniscribe doesn't like this font for some reason. // Returning FALSE will make the gfxGDIFont retry with the // "dumb" GDI shaper, unless useUniscribeOnly was set. result = false; break; } item.SaveGlyphs(aShapedText, aOffset); } RestoreDC(aDC, -1); return result; }
void plDynSurfaceWriter::plWinSurface::Allocate( uint16_t w, uint16_t h ) { int i; BITMAPINFO *bmi; Release(); fWidth = w; fHeight = h; /// Initialize a bitmap info struct to describe our surface if( IBitsPerPixel() == 8 ) bmi = (BITMAPINFO *)( new uint8_t[ sizeof( BITMAPINFOHEADER ) + sizeof( RGBQUAD ) * 256 ] ); else bmi = new BITMAPINFO; memset( &bmi->bmiHeader, 0, sizeof( BITMAPINFOHEADER ) ); bmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); bmi->bmiHeader.biWidth = (int)fWidth; bmi->bmiHeader.biHeight = -(int)fHeight; bmi->bmiHeader.biPlanes = 1; bmi->bmiHeader.biCompression = BI_RGB; bmi->bmiHeader.biBitCount = IBitsPerPixel(); if( IBitsPerPixel() == 8 ) { // Set up map for grayscale bitmap for( i = 0; i < 256; i++ ) { bmi->bmiColors[ i ].rgbRed = i; bmi->bmiColors[ i ].rgbGreen = i; bmi->bmiColors[ i ].rgbBlue = i; bmi->bmiColors[ i ].rgbReserved = i; } } /// Create a screen-compatible DC fDC = CreateCompatibleDC( nil ); if( fDC == nil ) { char msg[ 256 ]; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nil, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), msg, sizeof( msg ), nil ); char *ret = strrchr( msg, '\n' ); if( ret != nil ) *ret = 0; plStatusLog::AddLineS( "pipeline.log", 0xffff0000, "Unable to allocate DC for dynamic text map (%s, %d DCs allocated already)", msg, sNumDCsAllocated ); if (IBitsPerPixel() == 8 ) delete [] bmi; else delete bmi; return; } sNumDCsAllocated++; /// Create a bitmap using the DC and the bitmapInfo struct we filled out fBitmap = CreateDIBSection( fDC, bmi, DIB_RGB_COLORS, (void **)&fBits, nil, 0 ); if( fBitmap == nil ) { char msg[ 256 ]; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nil, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), msg, sizeof( msg ), nil ); char *ret = strrchr( msg, '\n' ); if( ret != nil ) *ret = 0; plStatusLog::AddLineS( "pipeline.log", 0xffff0000, "Unable to allocate RGB DIB section for dynamic text map (%s, %d bitmaps allocated already)", msg, sNumBitmapsAllocated ); if (IBitsPerPixel() == 8 ) delete [] bmi; else delete bmi; return; } sNumBitmapsAllocated++; /// Set up some basic props SetMapMode( fDC, MM_TEXT ); SetBkMode( fDC, TRANSPARENT ); SetTextAlign( fDC, TA_TOP | TA_LEFT ); fSaveNum = SaveDC( fDC ); SelectObject( fDC, fBitmap ); if (IBitsPerPixel() == 8 ) delete [] bmi; else delete bmi; }
static void test_savedc_2(void) { HWND hwnd; HDC hdc; HRGN hrgn; RECT rc, rc_clip; int ret; hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100, 0, 0, 0, NULL); assert(hwnd != 0); ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); hrgn = CreateRectRgn(0, 0, 0, 0); assert(hrgn != 0); hdc = GetDC(hwnd); ok(hdc != NULL, "GetDC failed\n"); ret = GetClipBox(hdc, &rc_clip); ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret); ret = GetClipRgn(hdc, hrgn); ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret); ret = GetRgnBox(hrgn, &rc); ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n", ret, rc.left, rc.top, rc.right, rc.bottom); /*dump_region(hrgn);*/ SetRect(&rc, 0, 0, 100, 100); ok(EqualRect(&rc, &rc_clip), "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom, rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom); ret = SaveDC(hdc); ok(ret == 1, "ret = %d\n", ret); ret = IntersectClipRect(hdc, 0, 0, 50, 50); if (ret == COMPLEXREGION) { /* XP returns COMPLEXREGION although dump_region reports only 1 rect */ trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret); /* let's make sure that it's a simple region */ ret = GetClipRgn(hdc, hrgn); ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret); dump_region(hrgn); } else ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret); ret = GetClipBox(hdc, &rc_clip); ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret); SetRect(&rc, 0, 0, 50, 50); ok(EqualRect(&rc, &rc_clip), "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom, rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom); ret = RestoreDC(hdc, 1); ok(ret, "ret = %d\n", ret); ret = GetClipBox(hdc, &rc_clip); ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret); SetRect(&rc, 0, 0, 100, 100); ok(EqualRect(&rc, &rc_clip), "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom, rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom); DeleteObject(hrgn); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); }
static void grid_paint(void* control, HDC dc, RECT* dirty, BOOL erase) { grid_t* grid = (grid_t*) control; RECT client; RECT rect; int header_w, header_h; int old_dc_state; int col0, row0; int x0, y0; int col, row; int col_count = grid->col_count; int row_count = grid->row_count; table_t* table = grid->table; table_cell_t* cell; GRID_TRACE("grid_paint(%p, %d, %d, %d, %d)", grid, dirty->left, dirty->top, dirty->right, dirty->bottom); if(table == NULL && !(grid->style & MC_GS_OWNERDATA)) return; old_dc_state = SaveDC(dc); GetClientRect(grid->win, &client); header_w = grid_header_width(grid); header_h = grid_header_height(grid); if(grid->font != NULL) SelectObject(dc, grid->font); SetBkMode(dc, TRANSPARENT); SetTextColor(dc, RGB(0,0,0)); SelectObject(dc, GetStockObject(BLACK_PEN)); /* Find 1st visible column */ rect.left = header_w - grid->scroll_x; for(col = 0; col < col_count; col++) { rect.right = rect.left + grid_col_width(grid, col); if(rect.right > header_w) { col0 = col; x0 = rect.left; break; } rect.left = rect.right; } /* Find 1st visible row */ rect.top = header_h - grid->scroll_y; for(row = 0; row < row_count; row++) { rect.bottom = rect.top + grid_row_height(grid, row); if(rect.bottom > header_h) { row0 = row; y0 = rect.top; break; } rect.top = rect.bottom; } /* If needed, send MC_GN_ODCACHEHINT */ if(grid->style & MC_GS_OWNERDATA) { WORD col1, row1; rect.right = x0; for(col1 = col0; col1+1 < grid->col_count; col1++) { rect.right += grid_col_width(grid, col1); if(rect.right >= client.right) break; } rect.bottom = y0; for(row1 = row0; row1+1 < grid->row_count; row1++) { rect.bottom += grid_row_height(grid, row1); if(rect.bottom >= client.bottom) break; } if(col0 != grid->cache_hint[0] || row0 != grid->cache_hint[1] || col1 != grid->cache_hint[2] || row1 != grid->cache_hint[3]) { MC_NMGCACHEHINT hint; hint.hdr.hwndFrom = grid->win; hint.hdr.idFrom = GetWindowLong(grid->win, GWL_ID); hint.hdr.code = MC_GN_ODCACHEHINT; hint.wColumnFrom = col0; hint.wRowFrom = row0; hint.wColumnTo = col1; hint.wRowTo = row1; GRID_TRACE("grid_paint: Sending MC_GN_ODCACHEHINT (%hu, %hu, %hu, %hu)", col0, row0, col1, row1); MC_SEND(grid->notify_win, WM_NOTIFY, hint.hdr.idFrom, &hint); grid->cache_hint[0] = col0; grid->cache_hint[1] = row0; grid->cache_hint[2] = col1; grid->cache_hint[3] = row1; } } /* Paint the "dead" top left header cell */ if(header_w > 0 && header_h > 0 && dirty->left < header_w && dirty->top < header_h) { mc_rect_set(&rect, 0, 0, grid->header_width, grid->header_height); mc_clip_set(dc, 0, 0, MC_MIN(header_w, client.right), MC_MIN(header_h, client.bottom)); grid_paint_header_cell(grid, MC_TABLE_HEADER, MC_TABLE_HEADER, NULL, dc, &rect, -1, 0); } /* Paint column headers */ if(header_h > 0 && dirty->top < header_h) { rect.left = x0; rect.top = 0; rect.bottom = header_h; for(col = col0; col < col_count; col++) { rect.right = rect.left + grid_col_width(grid, col); mc_clip_set(dc, MC_MAX(header_w, rect.left), rect.top, MC_MIN(rect.right, client.right), MC_MIN(rect.bottom, client.bottom)); grid_paint_header_cell(grid, col, MC_TABLE_HEADER, (table ? &table->cols[col] : NULL), dc, &rect, col, (grid->style & MC_GS_COLUMNHEADERMASK)); rect.left = rect.right; if(rect.right >= client.right) break; } } /* Paint row headers */ if(header_w > 0 && dirty->left <= header_w) { rect.left = 0; rect.top = y0; rect.right = header_w; for(row = row0; row < row_count; row++) { rect.bottom = rect.top + grid_row_height(grid, row); mc_clip_set(dc, rect.left, MC_MAX(header_h, rect.top), MC_MIN(rect.right, client.right), MC_MIN(rect.bottom, client.bottom)); grid_paint_header_cell(grid, MC_TABLE_HEADER, row, (table ? &table->rows[row] : NULL), dc, &rect, row, (grid->style & MC_GS_ROWHEADERMASK)); rect.top = rect.bottom; if(rect.bottom >= client.bottom) break; } } /* Paint grid lines */ if(!(grid->style & MC_GS_NOGRIDLINES)) { HPEN pen, old_pen; int x, y; mc_clip_set(dc, header_w, header_h, client.right, client.bottom); pen = CreatePen(PS_SOLID, 0, mcGetThemeSysColor(grid->theme_listview, COLOR_3DFACE)); old_pen = SelectObject(dc, pen); x = x0; y = header_h + grid->scroll_y_max - grid->scroll_y; for(col = col0; col < col_count; col++) { x += grid_col_width(grid, col); MoveToEx(dc, x-1, header_h, NULL); LineTo(dc, x-1, y); if(x >= client.right) break; } x = header_w + grid->scroll_x_max - grid->scroll_x; y = y0; for(row = 0; row < row_count; row++) { y += grid_row_height(grid, row); MoveToEx(dc, header_w, y-1, NULL); LineTo(dc, x, y-1); if(y >= client.bottom) break; } SelectObject(dc, old_pen); DeleteObject(pen); } /* Paint grid cells */ rect.top = y0; for(row = row0; row < row_count; row++) { rect.bottom = rect.top + grid_row_height(grid, row); rect.left = x0; for(col = col0; col < col_count; col++) { if(table != NULL) cell = table_cell(table, col, row); else cell = NULL; rect.right = rect.left + grid_col_width(grid, col); grid_paint_cell(grid, col, row, cell, dc, &rect); if(rect.right >= client.right) break; rect.left = rect.right; } if(rect.bottom >= client.bottom) break; rect.top = rect.bottom; } RestoreDC(dc, old_dc_state); }
LRESULT CALLBACK ProcessListWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HBRUSH hbrBackground; int count; RECT rcItem; RECT rcClip; HDC hDC; int DcSave; switch (message) { case WM_ERASEBKGND: /* * The list control produces a nasty flicker * when the user is resizing the window because * it erases the background to white, then * paints the list items over it. * * We will clip the drawing so that it only * erases the parts of the list control that * show only the background. */ /* * Get the device context and save its state * to be restored after we're done */ hDC = (HDC) wParam; DcSave = SaveDC(hDC); /* * Get the background brush */ hbrBackground = (HBRUSH) GetClassLongPtrW(hWnd, GCLP_HBRBACKGROUND); /* * Calculate the clip rect by getting the RECT * of the first and last items and adding them up. * * We also have to get the item's icon RECT and * subtract it from our clip rect because we don't * use icons in this list control. */ rcClip.left = LVIR_BOUNDS; SendMessageW(hWnd, LVM_GETITEMRECT, 0, (LPARAM) &rcClip); rcItem.left = LVIR_BOUNDS; count = SendMessageW(hWnd, LVM_GETITEMCOUNT, 0, 0); SendMessageW(hWnd, LVM_GETITEMRECT, count - 1, (LPARAM) &rcItem); rcClip.bottom = rcItem.bottom; rcItem.left = LVIR_ICON; SendMessageW(hWnd, LVM_GETITEMRECT, 0, (LPARAM) &rcItem); rcClip.left = rcItem.right; /* * Now exclude the clip rect */ ExcludeClipRect(hDC, rcClip.left, rcClip.top, rcClip.right, rcClip.bottom); /* * Now erase the background * * * FIXME: Should I erase it myself or * pass down the updated HDC and let * the default handler do it? */ GetClientRect(hWnd, &rcItem); FillRect(hDC, &rcItem, hbrBackground); /* * Now restore the DC state that we * saved earlier */ RestoreDC(hDC, DcSave); return TRUE; } /* * We pass on all messages except WM_ERASEBKGND */ return CallWindowProcW(OldProcessListWndProc, hWnd, message, wParam, lParam); }
// TODO code: optimise airspace drawing (same as DrawAirSpace()) // draw airspace using alpha blending //static void MapWindow::DrawTptAirSpace(HDC hdc, const RECT rc) { // since standard GDI functions (brushes, pens...) ignore alpha octet in ARGB // color value and don't set it in the resulting bitmap, we cannot use // perpixel alpha blending, instead we use global opacity for alpha blend // (same opacity for all pixels); for fully "transparent" areas (without // airspace) we must copy destination bitmap into source bitmap first so that // alpha blending of such areas results in the same pixels as origin pixels // in destination CAirspaceList::const_iterator it; CAirspaceList::const_reverse_iterator itr; const CAirspaceList& airspaces_to_draw = CAirspaceManager::Instance().GetNearAirspacesRef(); int airspace_type; bool found = false; bool borders_only = (GetAirSpaceFillType() == asp_fill_ablend_borders); bool outlined_only=(GetAirSpaceFillType()==asp_fill_border_only); static bool asp_selected_flash = false; asp_selected_flash = !asp_selected_flash; int nDC1 = SaveDC(mhdcbuffer); int nDC2 = SaveDC(hDCMask); int nDC3 = SaveDC(hDCTemp); // Draw airspace area if (1) { CCriticalSection::CGuard guard(CAirspaceManager::Instance().MutexRef()); if (borders_only) { // Draw in reverse order! // The idea behind this, is lower top level airspaces are smaller. (statistically) // They have to be draw later, because inside border area have to be in correct color, // not the color of the bigger airspace above this small one. for (itr=airspaces_to_draw.rbegin(); itr != airspaces_to_draw.rend(); ++itr) { if ((*itr)->DrawStyle() == adsFilled) { airspace_type = (*itr)->Type(); if (!found) { found = true; ClearTptAirSpace(hdc, rc); } // set filling brush SelectObject(mhdcbuffer, GetAirSpaceSldBrushByClass(airspace_type)); (*itr)->Draw(mhdcbuffer, rc, true); (*itr)->Draw(hDCMask, rc, false); } }//for } else { // Draw in direct order! for (it=airspaces_to_draw.begin(); it != airspaces_to_draw.end(); ++it) { if ((*it)->DrawStyle() == adsFilled) { airspace_type = (*it)->Type(); if (!found) { found = true; ClearTptAirSpace(hdc, rc); } // set filling brush SelectObject(hDCTemp, GetAirSpaceSldBrushByClass(airspace_type)); (*it)->Draw(hDCTemp, rc, true); } }//for }//else borders_only }//mutex release // alpha blending if (found) { if (borders_only) { MaskBlt(hDCTemp, rc.left,rc.top, rc.right-rc.left,rc.bottom-rc.top, mhdcbuffer,rc.left,rc.top, hMaskBitMap,rc.left,rc.top, MAKEROP4(SRCAND, 0x00AA0029)); } DoAlphaBlend(hdc, rc, hDCTemp, rc, (255 * GetAirSpaceOpacity()) / 100); } // draw it again, just the outlines // we will be drawing directly into given hdc, so store original PEN object HPEN hOrigPen = (HPEN) SelectObject(hdc, GetStockObject(WHITE_PEN)); if (1) { CCriticalSection::CGuard guard(CAirspaceManager::Instance().MutexRef()); for (it=airspaces_to_draw.begin(); it != airspaces_to_draw.end(); ++it) { if ((*it)->DrawStyle()) { airspace_type = (*it)->Type(); if ( (((*it)->DrawStyle()==adsFilled)&&!outlined_only&&!borders_only) ^ (asp_selected_flash && (*it)->Selected()) ) { SelectObject(hdc, GetStockObject(BLACK_PEN)); } else { SelectObject(hdc, hAirspacePens[airspace_type]); } (*it)->Draw(hdc, rc, false); } }//for } // restore original PEN SelectObject(hdc, hOrigPen); RestoreDC(mhdcbuffer, nDC1); RestoreDC(hDCMask, nDC2); RestoreDC(hDCTemp, nDC3); } // DrawTptAirSpace()
/*! \brief This function is responsible for drawing player, foods, background playing field and shows all the text in the game. As it prescribe management in our game. For control of the game and drawing the background playing field meets the code. \code switch (message) { case WM_CREATE: hBitmap = (HBITMAP)LoadImage(hInst, L"1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); break; case WM_KEYDOWN: switch (wParam) { //Repeat game case 'O': pause= !pause; break; case 'P': if(GameOver == 1) { GameOver=0; ship.health = 20; RECT r = {0,0,700,500}; for (int i=0;i<ASTEROID_COUNT;i++) { asteroids[i] = CreateAsteroid(r); } } break; } case WM_MOUSEMOVE: //Passing the coordinates of the mouse cursor. xPos = GET_X_LPARAM(lParam); targetx=xPos; yPos = GET_Y_LPARAM(lParam); targety=yPos; break; InvalidateRect(hWnd,NULL,1); break; \endcode This part of the code responsible for drawing player and foods. Drawing in WinApi performed using brushes and pens. With feathers, we draw the contours of our player and foods. With a brush paints we figure our color. \code case WM_PAINT: hdc = BeginPaint(hWnd, &ps); RECT rect; BITMAP bitmap; HDC hdcMem; HGDIOBJ oldBitmap; GetClientRect(hWnd, &rect); width=rect.right; height=rect.bottom; backbuffDC = CreateCompatibleDC(hdc); backbuffer = CreateCompatibleBitmap( hdc, width, height); savedDC = SaveDC(backbuffDC); SelectObject( backbuffDC, backbuffer ); // Draw HERE //clear window hBrush = CreateSolidBrush(RGB(255,0,255)); FillRect(backbuffDC,&rect,hBrush); DeleteObject(hBrush); hdcMem = CreateCompatibleDC(hdc);//! oldBitmap = SelectObject(hdcMem, hBitmap);//! //draw background GetObject(hBitmap, sizeof(bitmap), &bitmap);//! BitBlt(backbuffDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);//! //draw ball //Rectangle(backbuffDC,0, 0, 785, 663); //draw asteroids //Drawing food for (int i=0;i<ASTEROID_COUNT;i++) { hPen = CreatePen(PS_SOLID, 1, RGB(asteroids[i].dY, asteroids[i].dX, asteroids[i].dX+40)); hOldPen = (HPEN)SelectObject(backbuffDC, hPen); Ellipse(backbuffDC,asteroids[i].X-asteroids[i].r, asteroids[i].Y-asteroids[i].r,asteroids[i].X+asteroids[i].r,asteroids[i].Y+asteroids[i].r); SelectObject(backbuffDC, hOldPen); DeleteObject(hPen); hPen = CreatePen(PS_SOLID, asteroids[i].r, RGB(asteroids[i].dY, asteroids[i].dX, asteroids[i].dX+40)); hOldPen = (HPEN)SelectObject(backbuffDC, hPen); Ellipse(backbuffDC, asteroids[i].X - (asteroids[i].r/1.9), asteroids[i].Y - (asteroids[i].r/1.9),asteroids[i].X + (asteroids[i].r/1.9), asteroids[i].Y + (asteroids[i].r/1.9)); Ellipse(backbuffDC, asteroids[i].X - (asteroids[i].r/2.1), asteroids[i].Y - (asteroids[i].r/2.1),asteroids[i].X + (asteroids[i].r/2.1), asteroids[i].Y + (asteroids[i].r/2.1)); SelectObject(backbuffDC, hOldPen); DeleteObject(hPen); } //Drawing collor player hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); hOldPen = (HPEN)SelectObject(backbuffDC, hPen); Ellipse(backbuffDC,ship.X-ship.health,ship.Y-ship.health,ship.X+ship.health,ship.Y+ship.health); SelectObject(backbuffDC, hOldPen); DeleteObject(hPen); \endcode This part of the code responsible for entering text on a screen. To enter text on the screen creates an array of characters. Using this array, we can create the text. If the number of characters exceeds the specified number of the program will display an error. The text displayed on the screen at a certain place and under certain conditions. The implementation is shown below \code WCHAR s[30]; if(GameOver == 1){ wsprintf(s, _T("Game over!")); //Conclusion inscriptions "Game over!" TextOut(backbuffDC, 350, 250, s, wcslen(s)); wsprintf(s, _T("Replay enter P")); TextOut(backbuffDC, 350, 270, s, wcslen(s)); wsprintf(s,_T("score %d"),ship.health-20);// The conclusion points during the end game TextOut(backbuffDC,350,300,s,wcslen(s)); } else {wsprintf(s,_T("score %d"),ship.health-20);// The conclusion points during the game TextOut(backbuffDC,20,630,s,wcslen(s));} if(pause){ wsprintf(s, _T("Pause")); //Conclusion inscriptions "pause" TextOut(backbuffDC, 350, 250, s, wcslen(s)); } wsprintf(s,_T("ver 1.2.5"));//ver game TextOut(backbuffDC,700,630,s,wcslen(s)); wsprintf(s,_T("Replay enter P")); TextOut(backbuffDC,20,30,s,wcslen(s)); wsprintf(s,_T("Pause enter O")); TextOut(backbuffDC,20,50,s,wcslen(s)); \endcode */ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; int savedDC; HDC backbuffDC; int width, height; HBITMAP backbuffer; HBRUSH hBrush; int xPos, yPos; HPEN hPen, hOldPen; switch (message) { ///Paint background case WM_CREATE: hBitmap = (HBITMAP)LoadImage(hInst, L"1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); break; case WM_KEYDOWN: switch (wParam) { case 'O': pause= !pause; break; ///Repeat game case 'P': if(GameOver == 1) { GameOver=0; ship.health = 20; RECT r = {0,0,700,500}; for (int i=0;i<ASTEROID_COUNT;i++) { asteroids[i] = CreateAsteroid(r); } } break; } ///Passing the coordinates of the mouse cursor. case WM_MOUSEMOVE: xPos = GET_X_LPARAM(lParam); targetx=xPos; yPos = GET_Y_LPARAM(lParam); targety=yPos; break; InvalidateRect(hWnd,NULL,1); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); RECT rect; BITMAP bitmap; HDC hdcMem; HGDIOBJ oldBitmap; GetClientRect(hWnd, &rect); width=rect.right; height=rect.bottom; backbuffDC = CreateCompatibleDC(hdc); backbuffer = CreateCompatibleBitmap( hdc, width, height); savedDC = SaveDC(backbuffDC); SelectObject( backbuffDC, backbuffer ); ///clear window hBrush = CreateSolidBrush(RGB(255,0,255)); FillRect(backbuffDC,&rect,hBrush); DeleteObject(hBrush); hdcMem = CreateCompatibleDC(hdc);//! oldBitmap = SelectObject(hdcMem, hBitmap);//! ///draw background GetObject(hBitmap, sizeof(bitmap), &bitmap);//! BitBlt(backbuffDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);//! ///draw ball ///Rectangle(backbuffDC,0, 0, 785, 663); ///draw asteroids //Drawing food for (int i=0;i<ASTEROID_COUNT;i++) { hPen = CreatePen(PS_SOLID, 1, RGB(asteroids[i].dY, asteroids[i].dX, asteroids[i].dX+40)); hOldPen = (HPEN)SelectObject(backbuffDC, hPen); Ellipse(backbuffDC,asteroids[i].X-asteroids[i].r, asteroids[i].Y-asteroids[i].r,asteroids[i].X+asteroids[i].r,asteroids[i].Y+asteroids[i].r); SelectObject(backbuffDC, hOldPen); DeleteObject(hPen); hPen = CreatePen(PS_SOLID, asteroids[i].r, RGB(asteroids[i].dY, asteroids[i].dX, asteroids[i].dX+40)); hOldPen = (HPEN)SelectObject(backbuffDC, hPen); Ellipse(backbuffDC, asteroids[i].X - (asteroids[i].r/1.9), asteroids[i].Y - (asteroids[i].r/1.9),asteroids[i].X + (asteroids[i].r/1.9), asteroids[i].Y + (asteroids[i].r/1.9)); Ellipse(backbuffDC, asteroids[i].X - (asteroids[i].r/2.1), asteroids[i].Y - (asteroids[i].r/2.1),asteroids[i].X + (asteroids[i].r/2.1), asteroids[i].Y + (asteroids[i].r/2.1)); SelectObject(backbuffDC, hOldPen); DeleteObject(hPen); } ///Drawing collor player hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); hOldPen = (HPEN)SelectObject(backbuffDC, hPen); Ellipse(backbuffDC,ship.X-ship.health,ship.Y-ship.health,ship.X+ship.health,ship.Y+ship.health); SelectObject(backbuffDC, hOldPen); DeleteObject(hPen); WCHAR s[30]; if(GameOver == 1){ ///Conclusion inscriptions "Game over!" wsprintf(s, _T("Game over!")); TextOut(backbuffDC, 350, 250, s, wcslen(s)); wsprintf(s, _T("Replay enter P")); TextOut(backbuffDC, 350, 270, s, wcslen(s)); /// The conclusion points during the end game wsprintf(s,_T("score %d"),ship.health-20); TextOut(backbuffDC,350,300,s,wcslen(s)); } /// The conclusion points during the game else {wsprintf(s,_T("score %d"),ship.health-20); TextOut(backbuffDC,20,630,s,wcslen(s));} ///Conclusion inscriptions "pause" if(pause){ wsprintf(s, _T("Pause")); TextOut(backbuffDC, 350, 250, s, wcslen(s)); } wsprintf(s,_T("ver 1.2.5")); TextOut(backbuffDC,700,630,s,wcslen(s)); wsprintf(s,_T("Replay enter P")); TextOut(backbuffDC,20,30,s,wcslen(s)); wsprintf(s,_T("Pause enter O")); TextOut(backbuffDC,20,50,s,wcslen(s)); /// End application-specific layout section. BitBlt(hdc,0,0,width,height,backbuffDC,0,0,SRCCOPY); RestoreDC(backbuffDC,savedDC); DeleteObject(backbuffer); DeleteDC(backbuffDC); SelectObject(hdcMem, oldBitmap); DeleteDC(hdcMem); /// End drawing EndPaint(hWnd, &ps); break; /// Post Uninstall window background case WM_ERASEBKGND: return 1; /// The message about the destruction of the window case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); break; } return 0; }
static void DrawLayerButton(HDC dc, RECT rect, const sLayer& layer, bool pushed) { // get the menu color DWORD sys_color = GetSysColor(COLOR_MENU); RGB menu_color = { GetRValue(sys_color), GetGValue(sys_color), GetBValue(sys_color), }; RGB white = { 255, 255, 255 }; RGB black = { 0, 0, 0 }; if (pushed) { std::swap(white, black); } HPEN very_light = CreateShadedPen(menu_color, white, 64); HPEN light = CreateShadedPen(menu_color, white, 192); HPEN dark = CreateShadedPen(menu_color, black, 192); HPEN very_dark = CreateShadedPen(menu_color, black, 64); SaveDC(dc); SetROP2(dc, R2_COPYPEN); // draw the outer border SelectObject(dc, very_light); MoveToEx(dc, rect.left, rect.bottom - 1, NULL); LineTo(dc, rect.left, rect.top); LineTo(dc, rect.right - 1, rect.top); SelectObject(dc, very_dark); MoveToEx(dc, rect.left, rect.bottom - 1, NULL); LineTo(dc, rect.right - 1, rect.bottom - 1); LineTo(dc, rect.right - 1, rect.top); InflateRect(&rect, -1, -1); // draw the inner border SelectObject(dc, light); MoveToEx(dc, rect.left, rect.bottom - 1, NULL); LineTo(dc, rect.left, rect.top); LineTo(dc, rect.right - 1, rect.top); SelectObject(dc, dark); MoveToEx(dc, rect.left, rect.bottom - 1, NULL); LineTo(dc, rect.right - 1, rect.bottom - 1); LineTo(dc, rect.right - 1, rect.top); InflateRect(&rect, -1, -1); // draw the center of the button FillRect(dc, &rect, (HBRUSH)(COLOR_MENU + 1)); int y = (rect.bottom - rect.top) / 2; int icon = (layer.IsVisible() ? IDI_LAYER_VISIBLE : IDI_LAYER_INVISIBLE); DrawIconEx( dc, rect.left + y - 8, rect.top + y - 8, LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(icon)), 16, 16, 0, NULL, DI_NORMAL); rect.left += 18; SelectObject(dc, GetStockObject(DEFAULT_GUI_FONT)); SetTextColor(dc, 0x000000); SetBkColor(dc, 0xFFFFFF); SetBkMode(dc, TRANSPARENT); DrawText(dc, layer.GetName(), strlen(layer.GetName()), &rect, DT_CENTER | DT_VCENTER); // clean up RestoreDC(dc, -1); DeleteObject(very_light); DeleteObject(light); DeleteObject(dark); DeleteObject(very_dark); }
HFONT EzCreateFont (HDC hdc, TCHAR * szFaceName, int iDeciPtHeight, int iDeciPtWidth, int iAttributes, BOOL fLogRes) { FLOAT cxDpi, cyDpi ; HFONT hFont ; LOGFONT lf ; POINT pt ; TEXTMETRIC tm ; SaveDC (hdc) ; SetGraphicsMode (hdc, GM_ADVANCED) ; ModifyWorldTransform (hdc, NULL, MWT_IDENTITY) ; SetViewportOrgEx (hdc, 0, 0, NULL) ; SetWindowOrgEx (hdc, 0, 0, NULL) ; if (fLogRes) { cxDpi = (FLOAT) GetDeviceCaps (hdc, LOGPIXELSX) ; cyDpi = (FLOAT) GetDeviceCaps (hdc, LOGPIXELSY) ; } else { cxDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, HORZRES) / GetDeviceCaps (hdc, HORZSIZE)) ; cyDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, VERTRES) / GetDeviceCaps (hdc, VERTSIZE)) ; } pt.x = (int) (iDeciPtWidth * cxDpi / 72) ; pt.y = (int) (iDeciPtHeight * cyDpi / 72) ; DPtoLP (hdc, &pt, 1) ; lf.lfHeight = - (int) (fabs (pt.y) / 10.0 + 0.5) ; lf.lfWidth = 0 ; lf.lfEscapement = 0 ; lf.lfOrientation = 0 ; lf.lfWeight = iAttributes & EZ_ATTR_BOLD ? 700 : 0 ; lf.lfItalic = iAttributes & EZ_ATTR_ITALIC ? 1 : 0 ; lf.lfUnderline = iAttributes & EZ_ATTR_UNDERLINE ? 1 : 0 ; lf.lfStrikeOut = iAttributes & EZ_ATTR_STRIKEOUT ? 1 : 0 ; lf.lfCharSet = DEFAULT_CHARSET ; lf.lfOutPrecision = 0 ; lf.lfClipPrecision = 0 ; lf.lfQuality = 0 ; lf.lfPitchAndFamily = 0 ; lstrcpy (lf.lfFaceName, szFaceName) ; hFont = CreateFontIndirect (&lf) ; if (iDeciPtWidth != 0) { hFont = (HFONT) SelectObject (hdc, hFont) ; GetTextMetrics (hdc, &tm) ; DeleteObject (SelectObject (hdc, hFont)) ; lf.lfWidth = (int) (tm.tmAveCharWidth * fabs (pt.x) / fabs (pt.y) + 0.5) ; hFont = CreateFontIndirect (&lf) ; } RestoreDC (hdc, -1) ; return hFont ; }
static void test_TxGetNaturalSize(void) { HRESULT result; BOOL ret; /* This value is used when calling TxGetNaturalSize. MSDN says that this is not supported however a null pointer cannot be used as it will cause a segmentation violation. The values in the structure being pointed to are required to be INT_MAX otherwise calculations can give wrong values. */ const SIZEL psizelExtent = {INT_MAX,INT_MAX}; static const WCHAR oneA[] = {'A',0}; /* Results of measurements */ LONG xdim, ydim; /* The device context to do the tests in */ HDC hdcDraw; /* Variables with the text metric information */ INT charwidth_caps_text[26]; TEXTMETRICA tmInfo_text; if (!init_texthost()) return; hdcDraw = GetDC(NULL); SaveDC(hdcDraw); /* Populate the metric strucs */ SetMapMode(hdcDraw,MM_TEXT); GetTextMetricsA(hdcDraw, &tmInfo_text); SetLastError(0xdeadbeef); ret = GetCharWidth32A(hdcDraw,'A','Z',charwidth_caps_text); if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("GetCharWidth32 is not available\n"); goto cleanup; } /* Make measurements in MM_TEXT */ SetMapMode(hdcDraw,MM_TEXT); xdim = 0; ydim = 0; result = ITextServices_TxSetText(txtserv, oneA); ok(result == S_OK, "ITextServices_TxSetText failed (result = %x)\n", result); if (result != S_OK) { skip("Could not set text\n"); goto cleanup; } SetLastError(0xdeadbeef); result = ITextServices_TxGetNaturalSize(txtserv, DVASPECT_CONTENT, hdcDraw, NULL, NULL, TXTNS_FITTOCONTENT, &psizelExtent, &xdim, &ydim); todo_wine ok(result == S_OK || broken(result == E_FAIL), /* WINXP Arabic Language */ "TxGetNaturalSize gave unexpected return value (result = %x)\n", result); if (result == S_OK) { todo_wine ok(ydim == tmInfo_text.tmHeight, "Height calculated incorrectly (expected %d, got %d)\n", tmInfo_text.tmHeight, ydim); /* The native DLL adds one pixel extra when calculating widths. */ todo_wine ok(xdim >= charwidth_caps_text[0] && xdim <= charwidth_caps_text[0] + 1, "Width calculated incorrectly (expected %d {+1}, got %d)\n", charwidth_caps_text[0], xdim); } else skip("TxGetNaturalSize measurements not performed (xdim = %d, ydim = %d, result = %x, error = %x)\n", xdim, ydim, result, GetLastError()); cleanup: RestoreDC(hdcDraw,1); ReleaseDC(NULL,hdcDraw); free_texthost(); }
static void test_savedc(void) { HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); int ret; ok(hdc != NULL, "CreateDC rets %p\n", hdc); ret = SaveDC(hdc); ok(ret == 1, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 2, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 3, "ret = %d\n", ret); ret = RestoreDC(hdc, -1); ok(ret, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 3, "ret = %d\n", ret); ret = RestoreDC(hdc, 1); ok(ret, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 1, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 2, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 3, "ret = %d\n", ret); ret = RestoreDC(hdc, -2); ok(ret, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 2, "ret = %d\n", ret); ret = RestoreDC(hdc, -2); ok(ret, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 1, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 2, "ret = %d\n", ret); ret = RestoreDC(hdc, -4); ok(!ret, "ret = %d\n", ret); ret = RestoreDC(hdc, 3); ok(!ret, "ret = %d\n", ret); /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */ ret = RestoreDC(hdc, -3); ok(!ret || broken(ret), /* Win9x */ "ret = %d\n", ret); /* Trying to clear an empty save stack fails. */ ret = RestoreDC(hdc, -3); ok(!ret, "ret = %d\n", ret); ret = SaveDC(hdc); ok(ret == 3 || broken(ret == 1), /* Win9x */ "ret = %d\n", ret); /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */ ret = RestoreDC(hdc, 0); ok(!ret || broken(ret), /* Win9x */ "ret = %d\n", ret); /* Trying to clear an empty save stack fails. */ ret = RestoreDC(hdc, 0); ok(!ret, "ret = %d\n", ret); ret = RestoreDC(hdc, 1); ok(ret || broken(!ret), /* Win9x */ "ret = %d\n", ret); DeleteDC(hdc); }
void CDeviceView::OnPaint(HDC hDC) { HDC hBDC = NULL, hODC = NULL; CBitmap *pbm = NULL; if (!InRenderMode()) { hODC = hDC; pbm = CBitmap::Create(GetClientSize(), RGB(0, 0, 0), hDC); if (pbm != NULL) { hBDC = pbm->BeginPaintInto(); if (hBDC != NULL) hDC = hBDC; } } // Black-fill first SIZE fillsz = GetClientSize(); RECT fillrc = {0, 0, fillsz.cx, fillsz.cy}; FillRect(hDC, &fillrc, (HBRUSH)GetStockObject(BLACK_BRUSH)); if (m_pbmImage != NULL) m_pbmImage->Blend(hDC); BOOL bScroll = m_bScrollEnable && m_sb.m_hWnd; int sdc = 0; if (bScroll) { sdc = SaveDC(hDC); OffsetViewportOrgEx(hDC, 0, -m_nScrollOffset + g_iListHeaderHeight, NULL); } else if (m_bScrollEnable) { sdc = SaveDC(hDC); OffsetViewportOrgEx(hDC, 0, g_iListHeaderHeight, NULL); } int miny = 0 + m_nScrollOffset; int maxy = g_sizeImage.cy + m_nScrollOffset; int t, nt = GetNumTexts(); for (t = 0; t < nt; t++) { CDeviceViewText *pText = m_arpText[t]; if (pText != NULL && !(pText->GetMinY() > maxy || pText->GetMaxY() < miny)) pText->OnPaint(hDC); } BOOL bCFGUIEdit = m_ui.m_uig.InEditMode(); BOOL bEitherEditMode = bCFGUIEdit; int c, nc = GetNumControls(); for (c = 0; c < nc; c++) if (m_arpControl[c] != NULL && m_arpControl[c]->HasOverlay() && (m_arpControl[c]->IsHighlighted() ) && (bEitherEditMode || m_arpControl[c]->IsMapped())) m_arpControl[c]->DrawOverlay(hDC); for (c = 0; c < nc; c++) { CDeviceControl *pControl = m_arpControl[c]; if (pControl != NULL && (bEitherEditMode || pControl->IsMapped()) && !(pControl->GetMinY() > maxy || pControl->GetMaxY() < miny)) pControl->OnPaint(hDC); } if (bScroll || m_bScrollEnable) { RestoreDC(hDC, sdc); sdc = 0; } // Black fill the top portion if this is a list view if (bScroll) { GetClientRect(&fillrc); fillrc.bottom = g_iListHeaderHeight; FillRect(hDC, &fillrc, (HBRUSH)GetStockObject(BLACK_BRUSH)); } // Print out the headers TCHAR tszHeader[MAX_PATH]; // Control column if (m_arpText.GetSize()) { CPaintHelper ph(m_ui.m_uig, hDC); ph.SetElement(UIE_CALLOUT); for (int i = 0; i < 2; i++) { // Check if there are two columns, break out the 2nd iteration if not 2 columns. if (i == 1 && !(GetNumControls() > 1 && m_arpControl[0]->GetCalloutMaxRect().top == m_arpControl[1]->GetCalloutMaxRect().top)) break; RECT rcheader; if (m_arpText.GetSize()) { rcheader = m_arpText[i]->GetRect(); rcheader.bottom -= rcheader.top; rcheader.top = 0; LoadString(g_hModule, IDS_LISTHEADER_CTRL, tszHeader, MAX_PATH); DrawText(hDC, tszHeader, -1, &rcheader, DT_LEFT|DT_NOPREFIX|DT_CALCRECT); if (rcheader.right > m_arpText[i]->GetRect().right) rcheader.left -= rcheader.right - m_arpText[i]->GetRect().right; DrawText(hDC, tszHeader, -1, &rcheader, DT_LEFT|DT_NOPREFIX); // Action column rcheader = m_arpControl[i]->GetCalloutMaxRect(); rcheader.bottom -= rcheader.top; rcheader.top = 0; LoadString(g_hModule, IDS_LISTHEADER_ACTION, tszHeader, MAX_PATH); DrawText(hDC, tszHeader, -1, &rcheader, DT_CENTER|DT_NOPREFIX); } } } if (!InRenderMode()) { if (pbm != NULL) { if (hBDC != NULL) { pbm->EndPaintInto(hBDC); pbm->Draw(hODC); } delete pbm; } } }
///////////////////////////////////////////////////////////////////////////// // Name: DrawTextToDestDC // Description: Draws text for the CB to hDC // (into which one of the "m_bitmaps[???]" is selected) // // Entry: // HDC hDC - DC to which text is drawn // ("m_bitmaps[???]" is selected into it) // // CRect rect - part of client area (of the CB) to which // text is output // ///////////////////////////////////////////////////////////////////////////// void ZCheckBox::DrawTextToDestDC( HDC hDC, CRect& rect, int nState ) { if ( **m_pzsText == 0 ) return; int nIndexDC = SaveDC( hDC ); DWORD dwStyle = 0; SetBkMode( hDC, TRANSPARENT ); SelectObject( hDC, *m_pFont ); if ( m_bLeftText ) { rect.right -= BOX_SIZE + 6; dwStyle = DT_RIGHT; } else { rect.left += BOX_SIZE + 5; dwStyle = DT_LEFT; } rect.bottom -= 1; // rect = drawing rectangle inside hDC if ( nState == BOX_DISABLED_1 || nState == BOX_DISABLED_2 ) { if ( (m_ulMapActFlags & zMAPACT_DISABLE_READONLY) == 0 ) { SetTextColor( hDC, GetSysColor( COLOR_3DHILIGHT ) ); rect.OffsetRect( 1, 1 ); DrawText( hDC, *m_pzsText, -1, &rect, DT_SINGLELINE | DT_VCENTER | dwStyle ); SetTextColor( hDC, GetSysColor( COLOR_3DSHADOW ) ); rect.OffsetRect( -1, -1 ); } DrawText( hDC, *m_pzsText, -1, &rect, DT_SINGLELINE | DT_VCENTER | dwStyle ); } else { DrawText( hDC, *m_pzsText, -1, &rect, DT_SINGLELINE | DT_VCENTER | dwStyle ); } // calculate m_rectFocus int r_t = rect.right; // right side of text rectangle DrawText( hDC, *m_pzsText, -1, &rect, DT_SINGLELINE | DT_VCENTER | dwStyle | DT_CALCRECT ); CDC *pDC = CDC::FromHandle( hDC ); CRect rectClip; pDC->GetClipBox( &rectClip ); if ( rect.Width( ) > rectClip.Width( ) - BOX_SIZE -5 ) rect.right = rect.left + rectClip.Width( ) - BOX_SIZE - 5; else if ( m_bLeftText ) { int d = rect.right - rect.left; // text width d = r_t - d; rect.left += d; rect.right += d; } m_rectFocus = rect; RestoreDC( hDC, nIndexDC ); }