HDC WINAPI GetDC(HWND hwnd) { /* * Exclude update regions when drawing with GetDC. * This is required because some programs use GetDC * when painting outside of BeginPaint/EndPaint, and * the update region is empty then. */ return GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP|DCX_EXCLUDEUPDATE); }
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static int iKeep [NUM][4] ; HDC hdcScr, hdcMem ; int cx, cy ; HBITMAP hBitmap ; HWND hwnd ; int i, j, x1, y1, x2, y2 ; if (LockWindowUpdate (hwnd = GetDesktopWindow ())) { hdcScr = GetDCEx (hwnd, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE) ; hdcMem = CreateCompatibleDC (hdcScr) ; cx = GetSystemMetrics (SM_CXSCREEN) / 10 ; cy = GetSystemMetrics (SM_CYSCREEN) / 10 ; hBitmap = CreateCompatibleBitmap (hdcScr, cx, cy) ; SelectObject (hdcMem, hBitmap) ; srand ((int) GetCurrentTime ()) ; for (i = 0 ; i < 2 ; i++) for (j = 0 ; j < NUM ; j++) { if (i == 0) { iKeep [j] [0] = x1 = cx * (rand () % 10) ; iKeep [j] [1] = y1 = cy * (rand () % 10) ; iKeep [j] [2] = x2 = cx * (rand () % 10) ; iKeep [j] [3] = y2 = cy * (rand () % 10) ; } else { x1 = iKeep [NUM - 1 - j] [0] ; y1 = iKeep [NUM - 1 - j] [1] ; x2 = iKeep [NUM - 1 - j] [2] ; y2 = iKeep [NUM - 1 - j] [3] ; } BitBlt (hdcMem, 0, 0, cx, cy, hdcScr, x1, y1, SRCCOPY) ; BitBlt (hdcScr, x1, y1, cx, cy, hdcScr, x2, y2, SRCCOPY) ; BitBlt (hdcScr, x2, y2, cx, cy, hdcMem, 0, 0, SRCCOPY) ; Sleep (10) ; } DeleteDC (hdcMem) ; ReleaseDC (hwnd, hdcScr) ; DeleteObject (hBitmap) ; LockWindowUpdate (NULL) ; } return FALSE ; }
HRESULT CDECL wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *swapchain, struct wined3d_gamma_ramp *ramp) { HDC dc; TRACE("swapchain %p, ramp %p.\n", swapchain, ramp); dc = GetDCEx(swapchain->device_window, 0, DCX_USESTYLE | DCX_CACHE); GetDeviceGammaRamp(dc, ramp); ReleaseDC(swapchain->device_window, dc); return WINED3D_OK; }
static void hugsprim_GetDCEx_33(HugsStackPtr hugs_root) { HsPtr arg1; HsPtr arg2; HsWord32 arg3; HsPtr res1; arg1 = hugs->getPtr(); arg2 = hugs->getPtr(); arg3 = hugs->getWord32(); res1 = GetDCEx(arg1, arg2, arg3); hugs->putPtr(res1); hugs->returnIO(hugs_root,1); }
HDC WINAPI BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint) { HDC hdc; /* first update non-client area*/ if(mwforceNCpaint || hwnd->paintNC != mwpaintNC) { MwPaintNCArea(hwnd); hwnd->paintNC = mwpaintNC; } /* If ERASEMOVE: * Don't allow windows to repaint while user is moving * a window. Instead, just erase backgrounds * and indicate delayed painting required, which * will occur after user completes window move. */ if(mwERASEMOVE && dragwp) { hdc = NULL; lpPaint->fErase = !DefWindowProc(hwnd, WM_ERASEBKGND, 0, 0L); hwnd->gotPaintMsg = PAINT_DELAYPAINT; } else { HideCaret(hwnd); /* FIXME: mdemo requires update excluded or draw errors occur*/ hdc = GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP |DCX_EXCLUDEUPDATE); /* FIXME - bug*/ /* erase client background, always w/alpha blending*/ if(hwnd->nEraseBkGnd > 0 || mwforceNCpaint) lpPaint->fErase = !SendMessage(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0L); else lpPaint->fErase = 0; hwnd->nEraseBkGnd = 0; } lpPaint->hdc = hdc; if( hwnd->paintBrush != NULL ) DeleteObject ( hwnd->paintBrush ); if( hwnd->paintPen != NULL ) DeleteObject ( hwnd->paintPen ); hwnd->paintBrush = NULL; hwnd->paintPen = NULL; GetUpdateRect(hwnd, &lpPaint->rcPaint, FALSE); return hdc; }
HRESULT CDECL wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain, DWORD flags, const struct wined3d_gamma_ramp *ramp) { HDC dc; TRACE("swapchain %p, flags %#x, ramp %p.\n", swapchain, flags, ramp); if (flags) FIXME("Ignoring flags %#x.\n", flags); dc = GetDCEx(swapchain->device_window, 0, DCX_USESTYLE | DCX_CACHE); SetDeviceGammaRamp(dc, (void *)ramp); ReleaseDC(swapchain->device_window, dc); return WINED3D_OK; }
/* Helper function that blits the front buffer contents to the target window. */ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) { struct wined3d_surface *front; POINT offset = {0, 0}; HDC src_dc, dst_dc; RECT draw_rect; HWND window; TRACE("swapchain %p, rect %s.\n", swapchain, wine_dbgstr_rect(rect)); front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); if (swapchain->palette) wined3d_palette_apply_to_dc(swapchain->palette, front->hDC); if (front->resource.map_count) ERR("Trying to blit a mapped surface.\n"); TRACE("Copying surface %p to screen.\n", front); surface_load_location(front, NULL, WINED3D_LOCATION_DIB); src_dc = front->hDC; window = swapchain->win_handle; dst_dc = GetDCEx(window, 0, DCX_CLIPSIBLINGS | DCX_CACHE); /* Front buffer coordinates are screen coordinates. Map them to the * destination window if not fullscreened. */ if (swapchain->desc.windowed) ClientToScreen(window, &offset); TRACE("offset %s.\n", wine_dbgstr_point(&offset)); draw_rect.left = 0; draw_rect.right = front->resource.width; draw_rect.top = 0; draw_rect.bottom = front->resource.height; if (rect) IntersectRect(&draw_rect, &draw_rect, rect); BitBlt(dst_dc, draw_rect.left - offset.x, draw_rect.top - offset.y, draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top, src_dc, draw_rect.left, draw_rect.top, SRCCOPY); ReleaseDC(window, dst_dc); }
static HRESULT WINAPI IWineD3DClipperImpl_GetClipList(IWineD3DClipper *iface, const RECT *Rect, RGNDATA *ClipList, DWORD *Size) { IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface; TRACE("(%p,%p,%p,%p)\n", This, Rect, ClipList, Size); if (This->hWnd) { HDC hDC = GetDCEx(This->hWnd, NULL, DCX_WINDOW); if (hDC) { HRGN hRgn = CreateRectRgn(0,0,0,0); if (GetRandomRgn(hDC, hRgn, SYSRGN)) { if (GetVersion() & 0x80000000) { /* map region to screen coordinates */ POINT org; GetDCOrgEx( hDC, &org ); OffsetRgn( hRgn, org.x, org.y ); } if (Rect) { HRGN hRgnClip = CreateRectRgn(Rect->left, Rect->top, Rect->right, Rect->bottom); CombineRgn(hRgn, hRgn, hRgnClip, RGN_AND); DeleteObject(hRgnClip); } *Size = GetRegionData(hRgn, *Size, ClipList); } DeleteObject(hRgn); ReleaseDC(This->hWnd, hDC); } return WINED3D_OK; } else { static int warned = 0; if (warned++ < 10) FIXME("(%p,%p,%p,%p),stub!\n",This,Rect,ClipList,Size); if (Size) *Size=0; return WINEDDERR_NOCLIPLIST; } }
GLFont::GLFont() { m_name.clear(); m_dropShadowOffset = 1; m_pointSize = 0; m_cellHeight = 0; m_cellWidth = 0; m_charHeight = 0; m_charAvgWidth = 0; m_charMaxWidth = 0; m_numCharsToDraw = 0; m_textureObject = 0; m_drawDropShadows = false; m_color[0] = m_color[1] = m_color[2] = m_color[3] = 1.0f; m_pVertex = 0; m_hFont = 0; memset(m_glyphs, 0, sizeof(m_glyphs)); if (!m_logPixelsY) { HWND hWndDesktop = GetDesktopWindow(); HDC hDC = GetDCEx(hWndDesktop, 0, DCX_CACHE | DCX_WINDOW); if (hDC) { m_logPixelsY = GetDeviceCaps(hDC, LOGPIXELSY); ReleaseDC(hWndDesktop, hDC); } } if (!m_lfQuality) { DWORD dwVersion = GetVersion(); DWORD dwMajorVersion = static_cast<DWORD>((LOBYTE(LOWORD(dwVersion)))); DWORD dwMinorVersion = static_cast<DWORD>((HIBYTE(LOWORD(dwVersion)))); // Windows XP and higher will support ClearType quality fonts. if (dwMajorVersion >= 6 || (dwMajorVersion == 5 && dwMinorVersion == 1)) m_lfQuality = CLEARTYPE_QUALITY; else m_lfQuality = ANTIALIASED_QUALITY; } }
/***************************************************************** * CARET_DisplayCaret */ static void CARET_DisplayCaret( HWND hwnd, const RECT *r ) { HDC hdc; HDC hCompDC; /* do not use DCX_CACHE here, for x,y,width,height are in logical units */ if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE /*| DCX_CACHE*/ ))) return; hCompDC = CreateCompatibleDC(hdc); if (hCompDC) { HBITMAP hPrevBmp; hPrevBmp = SelectObject(hCompDC, Caret.hBmp); BitBlt(hdc, r->left, r->top, r->right-r->left, r->bottom-r->top, hCompDC, 0, 0, SRCINVERT); SelectObject(hCompDC, hPrevBmp); DeleteDC(hCompDC); } ReleaseDC( hwnd, hdc ); }
/* Helper function that blits the front buffer contents to the target window. */ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) { const struct wined3d_surface *front; POINT offset = {0, 0}; HDC src_dc, dst_dc; RECT draw_rect; HWND window; TRACE("swapchain %p, rect %s.\n", swapchain, wine_dbgstr_rect(rect)); front = swapchain->front_buffer; if (!(front->resource.usage & WINED3DUSAGE_RENDERTARGET)) return; if (front->flags & SFLAG_LOCKED) ERR("Trying to blit a mapped surface.\n"); TRACE("Copying surface %p to screen.\n", front); src_dc = front->hDC; window = swapchain->win_handle; dst_dc = GetDCEx(window, 0, DCX_CLIPSIBLINGS | DCX_CACHE); /* Front buffer coordinates are screen coordinates. Map them to the * destination window if not fullscreened. */ if (swapchain->desc.windowed) ClientToScreen(window, &offset); TRACE("offset %s.\n", wine_dbgstr_point(&offset)); draw_rect.left = 0; draw_rect.right = front->resource.width; draw_rect.top = 0; draw_rect.bottom = front->resource.height; if (rect) IntersectRect(&draw_rect, &draw_rect, rect); BitBlt(dst_dc, draw_rect.left - offset.x, draw_rect.top - offset.y, draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top, src_dc, draw_rect.left, draw_rect.top, SRCCOPY); ReleaseDC(window, dst_dc); }
static VOID Run(VOID) { HWND hDesktopWnd; HDC hdcDesktop, hdcMem; /* Get the screen size */ g_pInfo->cx = GetSystemMetrics(SM_CXSCREEN); g_pInfo->cy = GetSystemMetrics(SM_CYSCREEN); hDesktopWnd = GetDesktopWindow(); /* Get the DC for the desktop */ hdcDesktop = GetDCEx(hDesktopWnd, NULL, DCX_CACHE); if (hdcDesktop) { /* Initialize the base background onto a DC */ hdcMem = DrawBaseBackground(hdcDesktop); if (hdcMem) { /* TEST : Draw logoff screen */ DrawLogoffScreen(hdcMem); /* Blit the off-screen DC to the desktop */ BitBlt(hdcDesktop, 0, 0, g_pInfo->cx, g_pInfo->cy, hdcMem, 0, 0, SRCCOPY); /* Delete the memory DC */ DeleteDC(hdcMem); } /* Release the desktop DC */ ReleaseDC(hDesktopWnd, hdcDesktop); } }
/* Draw themed border */ static void nc_paint (HTHEME theme, HWND hwnd, HRGN region) { HRGN cliprgn = region; DWORD exStyle = GetWindowLongW (hwnd, GWL_EXSTYLE); if (exStyle & WS_EX_CLIENTEDGE) { HDC dc; RECT r; int cxEdge = GetSystemMetrics (SM_CXEDGE), cyEdge = GetSystemMetrics (SM_CYEDGE); int part = EP_EDITTEXT; int state = ETS_NORMAL; DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE); if (!IsWindowEnabled (hwnd)) state = ETS_DISABLED; else if (dwStyle & ES_READONLY) state = ETS_READONLY; else if (GetFocus() == hwnd) state = ETS_FOCUSED; GetWindowRect(hwnd, &r); /* New clipping region passed to default proc to exclude border */ cliprgn = CreateRectRgn (r.left + cxEdge, r.top + cyEdge, r.right - cxEdge, r.bottom - cyEdge); if (region != (HRGN)1) CombineRgn (cliprgn, cliprgn, region, RGN_AND); OffsetRect(&r, -r.left, -r.top); dc = GetDCEx(hwnd, region, DCX_WINDOW|DCX_INTERSECTRGN); OffsetRect(&r, -r.left, -r.top); if (IsThemeBackgroundPartiallyTransparent (theme, part, state)) DrawThemeParentBackground(hwnd, dc, &r); DrawThemeBackground (theme, dc, part, state, &r, 0); ReleaseDC(hwnd, dc); } /* Call default proc to get the scrollbars etc. also painted */ DefWindowProcW (hwnd, WM_NCPAINT, (WPARAM)cliprgn, 0); }
void VDVideoWindow::NCPaint(HRGN hrgn) { HDC hdc; // MSDN docs are in error -- if you do not include 0x10000, GetDCEx() will // return NULL but still won't set an error flag. Feng Yuan's Windows // Graphics book calls this the "undocumented flag that makes GetDCEx() // succeed" flag. ^^; // // WINE's source code documents it as DCX_USESTYLE, which makes more sense, // and that is the way WINE's DefWindowProc() handles WM_NCPAINT. This is // a cleaner solution than using DCX_CACHE, which also works but overrides // CS_OWNDC and CS_PARENTDC. I'm not going to argue with years of reverse // engineering. // // NOTE: Using DCX_INTERSECTRGN as recommended by MSDN causes Windows 98 // GDI to intermittently crash! hdc = GetDCEx(mhwnd, NULL, DCX_WINDOW|0x10000); if (hdc) { RECT rc; GetWindowRect(mhwnd, &rc); if ((WPARAM)hrgn > 1) { OffsetClipRgn(hdc, rc.left, rc.top); ExtSelectClipRgn(hdc, hrgn, RGN_AND); OffsetClipRgn(hdc, -rc.left, -rc.top); } OffsetRect(&rc, -rc.left, -rc.top); DrawEdge(hdc, &rc, BDR_RAISEDOUTER|BDR_RAISEDINNER, BF_RECT); rc.left += 2; rc.right -= 2; rc.top += 2; rc.bottom -= 2; DrawEdge(hdc, &rc, BDR_SUNKENOUTER|BDR_SUNKENINNER, BF_RECT); ReleaseDC(mhwnd, hdc); } }
bool GLFont::extractFontMetrics() { HWND hWndDesktop = GetDesktopWindow(); HDC hDC = GetDCEx(hWndDesktop, 0, DCX_CACHE | DCX_WINDOW); if (!hDC) return false; HFONT hPrevFont = reinterpret_cast<HFONT>(SelectObject(hDC, m_hFont)); TEXTMETRIC tm; SIZE charSize = {0}; char szString[2] = {0}; char szName[128] = {0}; GetTextFace(hDC, 128, szName); m_name = szName; GetTextMetrics(hDC, &tm); m_charHeight = m_cellHeight = tm.tmHeight + tm.tmExternalLeading; m_charMaxWidth = 0; m_charAvgWidth = 0; for (int c = 32; c < 127; ++c) { szString[0] = c; GetTextExtentPoint32(hDC, szString, 1, &charSize); if (charSize.cx > m_charMaxWidth) m_charMaxWidth = charSize.cx; m_charAvgWidth += charSize.cx; m_glyphs[c - 32].width = charSize.cx; } m_charAvgWidth /= TOTAL_CHARS; m_cellWidth = m_charMaxWidth + (m_charAvgWidth / 2); SelectObject(hDC, hPrevFont); ReleaseDC(hWndDesktop, hDC); return true; }
/* needed only for XORMOVE repaint algorithm*/ static void DrawXORFrame(HWND hwnd,int x, int y, BOOL bDrawCurrent) { HDC hdc; RECT rc; hdc = GetDCEx(NULL, NULL, DCX_WINDOW|DCX_EXCLUDEUPDATE); SelectObject(hdc, GetStockObject(NULL_BRUSH)); SelectObject(hdc, GetStockObject(WHITE_PEN)); GdSetMode(MWMODE_XOR); if(!IsRectEmpty(&lastrc)) Rectangle(hdc, lastrc.left, lastrc.top, lastrc.right, lastrc.bottom); GetWindowRect(hwnd, &rc); SetRect(&lastrc, rc.left+x, rc.top+y, rc.right+x, rc.bottom+y); if(bDrawCurrent) Rectangle(hdc, lastrc.left, lastrc.top, lastrc.right, lastrc.bottom); ReleaseDC(NULL, hdc); GdSetMode(MWMODE_SET); }
static void PaintWindowThread(void *) { /* First tell the main thread we're started */ _draw_mutex->BeginCritical(); _draw_mutex->SendSignal(); /* Do our best to make sure the main thread is the one that * gets the signal, and not our wait below. */ Sleep(0); /* Now wait for the first thing to draw! */ _draw_mutex->WaitForSignal(); while (_draw_continue) { /* Convert update region from logical to device coordinates. */ POINT pt = {0, 0}; ClientToScreen(_wnd.main_wnd, &pt); OffsetRect(&_wnd.update_rect, pt.x, pt.y); /* Create a device context that is clipped to the region we need to draw. * GetDCEx 'consumes' the update region, so we may not destroy it ourself. */ HRGN rgn = CreateRectRgnIndirect(&_wnd.update_rect); HDC dc = GetDCEx(_wnd.main_wnd, rgn, DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_INTERSECTRGN); PaintWindow(dc); /* Clear update rect. */ SetRectEmpty(&_wnd.update_rect); ReleaseDC(_wnd.main_wnd, dc); /* Flush GDI buffer to ensure drawing here doesn't conflict with any GDI usage in the main WndProc. */ GdiFlush(); _draw_mutex->WaitForSignal(); } _draw_mutex->EndCritical(); _draw_thread->Exit(); }
bool Bitmap::loadDesktop() { // Takes a screen capture of the current Windows desktop and stores // the image in the Bitmap object. HWND hDesktop = GetDesktopWindow(); if (!hDesktop) return false; int desktopWidth = GetSystemMetrics(SM_CXSCREEN); int desktopHeight = GetSystemMetrics(SM_CYSCREEN); HDC hDesktopDC = GetDCEx(hDesktop, 0, DCX_CACHE | DCX_WINDOW); if (!hDesktopDC) return false; if (!create(desktopWidth, desktopHeight)) { ReleaseDC(hDesktop, hDesktopDC); return false; } selectObject(); if (!BitBlt(dc, 0, 0, width, height, hDesktopDC, 0, 0, SRCCOPY)) { destroy(); ReleaseDC(hDesktop, hDesktopDC); return false; } deselectObject(); ReleaseDC(hDesktop, hDesktopDC); return true; }
static LRESULT PAGER_NCPaint (PAGER_INFO* infoPtr, HRGN hRgn) { RECT rcBottomRight, rcTopLeft; HDC hdc; if (infoPtr->dwStyle & WS_MINIMIZE) return 0; DefWindowProcW (infoPtr->hwndSelf, WM_NCPAINT, (WPARAM)hRgn, 0); if (!(hdc = GetDCEx (infoPtr->hwndSelf, 0, DCX_USESTYLE | DCX_WINDOW))) return 0; PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, FALSE); PAGER_DrawButton(hdc, infoPtr->clrBk, rcTopLeft, infoPtr->dwStyle & PGS_HORZ, TRUE, infoPtr->TLbtnState); PAGER_DrawButton(hdc, infoPtr->clrBk, rcBottomRight, infoPtr->dwStyle & PGS_HORZ, FALSE, infoPtr->BRbtnState); ReleaseDC( infoPtr->hwndSelf, hdc ); return 0; }
/***************************************************************************** * x11_copy_to_screen * * Helper function that blts the front buffer contents to the target window * * Params: * This: Surface to copy from * rc: Rectangle to copy * *****************************************************************************/ static void x11_copy_to_screen(IWineD3DSurfaceImpl *This, LPRECT rc) { if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) { POINT offset = {0,0}; HWND hDisplayWnd; HDC hDisplayDC; HDC hSurfaceDC = 0; RECT drawrect; TRACE("(%p)->(%p): Copying to screen\n", This, rc); hSurfaceDC = This->hDC; hDisplayWnd = This->resource.wineD3DDevice->ddraw_window; hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE); if(rc) { TRACE(" copying rect (%d,%d)->(%d,%d), offset (%d,%d)\n", rc->left, rc->top, rc->right, rc->bottom, offset.x, offset.y); } /* Front buffer coordinates are screen coordinates. Map them to the destination * window if not fullscreened */ if(!This->resource.wineD3DDevice->ddraw_fullscreen) { ClientToScreen(hDisplayWnd, &offset); } #if 0 /* FIXME: this doesn't work... if users really want to run * X in 8bpp, then we need to call directly into display.drv * (or Wine's equivalent), and force a private colormap * without default entries. */ if (This->palette) { SelectPalette(hDisplayDC, This->palette->hpal, FALSE); RealizePalette(hDisplayDC); /* sends messages => deadlocks */ } #endif drawrect.left = 0; drawrect.right = This->currentDesc.Width; drawrect.top = 0; drawrect.bottom = This->currentDesc.Height; #if 0 /* TODO: Support clippers */ if (This->clipper) { RECT xrc; HWND hwnd = ((IWineD3DClipperImpl *) This->clipper)->hWnd; if (hwnd && GetClientRect(hwnd,&xrc)) { OffsetRect(&xrc,offset.x,offset.y); IntersectRect(&drawrect,&drawrect,&xrc); } } #endif if (rc) { IntersectRect(&drawrect,&drawrect,rc); } else { /* Only use this if the caller did not pass a rectangle, since * due to double locking this could be the wrong one ... */ if (This->lockedRect.left != This->lockedRect.right) { IntersectRect(&drawrect,&drawrect,&This->lockedRect); } } BitBlt(hDisplayDC, drawrect.left-offset.x, drawrect.top-offset.y, drawrect.right-drawrect.left, drawrect.bottom-drawrect.top, hSurfaceDC, drawrect.left, drawrect.top, SRCCOPY); ReleaseDC(hDisplayWnd, hDisplayDC); } }
/* * doCapture * * Do the capture. Accepts the window * handle to be captured or the NULL value * to specify the root window. */ static int doCapture(HWND selectedHwnd) { HDC hdcSrc; HDC hdcCompat; HRGN capRegion; HWND oldForeground; RECT rect; HBITMAP hbm; /* Try and get everything out of the way before the * capture. */ Sleep(500 + winsnapvals.delay * 1000); /* Are we capturing a window or the whole screen */ if (selectedHwnd) { /* Set to foreground window */ oldForeground = GetForegroundWindow(); SetForegroundWindow(selectedHwnd); BringWindowToTop(selectedHwnd); Sleep(500); /* Build a region for the capture */ GetWindowRect(selectedHwnd, &rect); capRegion = CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom); if (!capRegion) { formatWindowsError(buffer, sizeof buffer); g_error("Error creating region: %s", buffer); return FALSE; } /* Get the device context for the selected * window. Create a memory DC to use for the * Bit copy. */ hdcSrc = GetDCEx(selectedHwnd, capRegion, DCX_WINDOW | DCX_PARENTCLIP | DCX_INTERSECTRGN); } else { /* Get the device context for the whole screen */ hdcSrc = CreateDC("DISPLAY", NULL, NULL, NULL); /* Get the screen's rectangle */ rect.top = 0; rect.bottom = GetDeviceCaps(hdcSrc, VERTRES); rect.left = 0; rect.right = GetDeviceCaps(hdcSrc, HORZRES); } if (!hdcSrc) { formatWindowsError(buffer, sizeof buffer); g_error("Error getting device context: %s", buffer); return FALSE; } hdcCompat = CreateCompatibleDC(hdcSrc); if (!hdcCompat) { formatWindowsError(buffer, sizeof buffer); g_error("Error getting compat device context: %s", buffer); return FALSE; } /* Do the window capture */ hbm = primDoWindowCapture(hdcSrc, hdcCompat, rect); if (!hbm) return FALSE; /* Release the device context */ ReleaseDC(selectedHwnd, hdcSrc); /* Replace the previous foreground window */ if (selectedHwnd && oldForeground) SetForegroundWindow(oldForeground); /* Send the bitmap */ if (hbm != NULL) { sendBMPToGimp(hbm, hdcCompat, rect); } return TRUE; }
/*********************************************************************** * ScrollBarWndProc */ LRESULT WINAPI ScrollBarWndProc(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) { #ifdef __ODYSSEY__ // Do this now, remove after Server side is fixed. PWND pWnd; pWnd = ValidateHwnd(Wnd); if (pWnd) { if (!pWnd->fnid) { NtUserSetWindowFNID(Wnd, FNID_SCROLLBAR); } } #endif if (! IsWindow(Wnd)) { return 0; } switch (Msg) { case WM_CREATE: IntScrollCreateScrollBar(Wnd, (LPCREATESTRUCTW) lParam); break; #ifdef __ODYSSEY__ case WM_DESTROY: NtUserSetWindowFNID(Wnd, FNID_DESTROY); return DefWindowProc(Wnd, Msg, wParam, lParam ); #endif //#if 0 /* FIXME */ case WM_ENABLE: { // SCROLLBAR_INFO *infoPtr; // if ((infoPtr = SCROLL_GetScrollBarInfo( hwnd, SB_CTL ))) // { // infoPtr->flags = wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH; // SCROLL_RefreshScrollBar(hwnd, SB_CTL, TRUE, TRUE); // } HDC hdc; DbgPrint("ScrollBarWndProc WM_ENABLE\n"); NtUserEnableScrollBar(Wnd,SB_CTL,(wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH)); /* Refresh Scrollbars. */ hdc = GetDCEx( Wnd, 0, DCX_CACHE ); if (!hdc) return 1; IntDrawScrollBar( Wnd, hdc, SB_CTL); ReleaseDC( Wnd, hdc ); } return 0; //#endif case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: { POINT Pt; Pt.x = (short)LOWORD(lParam); Pt.y = (short)HIWORD(lParam); ScrollTrackScrollBar(Wnd, SB_CTL, Pt); } break; case WM_LBUTTONUP: case WM_MOUSEMOVE: case WM_SYSTIMER: { POINT Pt; Pt.x = (short)LOWORD(lParam); Pt.y = (short)HIWORD(lParam); IntScrollHandleScrollEvent(Wnd, SB_CTL, Msg, Pt); } break; case WM_KEYDOWN: IntScrollHandleKbdEvent(Wnd, wParam, lParam); break; case WM_KEYUP: ShowCaret(Wnd); break; case WM_SETFOCUS: { /* Create a caret when a ScrollBar get focus */ RECT Rect; int ArrowSize, ThumbSize, ThumbPos, Vertical; Vertical = IntScrollGetScrollBarRect(Wnd, SB_CTL, &Rect, &ArrowSize, &ThumbSize, &ThumbPos); if (! Vertical) { CreateCaret(Wnd, (HBITMAP) 1, ThumbSize - 2, Rect.bottom - Rect.top - 2); SetCaretPos(ThumbPos + 1, Rect.top + 1); } else { CreateCaret(Wnd, (HBITMAP) 1, Rect.right - Rect.left - 2, ThumbSize - 2); SetCaretPos(Rect.top + 1, ThumbPos + 1); } ShowCaret(Wnd); } break; case WM_KILLFOCUS: { RECT Rect; int ArrowSize, ThumbSize, ThumbPos, Vertical; Vertical = IntScrollGetScrollBarRect(Wnd, SB_CTL, &Rect, &ArrowSize, &ThumbSize, &ThumbPos); if (! Vertical) { Rect.left = ThumbPos + 1; Rect.right = Rect.left + ThumbSize; } else { Rect.top = ThumbPos + 1; Rect.bottom = Rect.top + ThumbSize; } HideCaret(Wnd); InvalidateRect(Wnd, &Rect, FALSE); DestroyCaret(); } break; case WM_ERASEBKGND: return 1; case WM_GETDLGCODE: return DLGC_WANTARROWS; /* Windows returns this value */ case WM_PAINT: { PAINTSTRUCT Ps; HDC Dc; Dc = (0 != wParam ? (HDC) wParam : BeginPaint(Wnd, &Ps)); if (GetWindowLongPtrW(Wnd, GWL_STYLE) & SBS_SIZEGRIP) { IntScrollDrawSizeGrip(Wnd, Dc); } else if (0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & SBS_SIZEBOX)) { RECT Rect; GetClientRect(Wnd, &Rect); FillRect(Dc, &Rect, GetSysColorBrush(COLOR_SCROLLBAR)); } else { IntDrawScrollBar(Wnd, Dc, SB_CTL/*, TRUE, TRUE*/); } if (0 == wParam) { EndPaint(Wnd, &Ps); } } break; case SBM_SETPOS: return SetScrollPos(Wnd, SB_CTL, wParam, (BOOL) lParam); case SBM_GETPOS: return IntScrollGetScrollPos(Wnd, SB_CTL); case SBM_SETRANGEREDRAW: case SBM_SETRANGE: { INT OldPos = IntScrollGetScrollPos(Wnd, SB_CTL); SetScrollRange(Wnd, SB_CTL, wParam, lParam, FALSE); if (Msg == SBM_SETRANGEREDRAW) SCROLL_RefreshScrollBar( Wnd, SB_CTL, TRUE, TRUE ); if (OldPos != IntScrollGetScrollPos(Wnd, SB_CTL)) return OldPos; } return 0; case SBM_GETRANGE: return IntScrollGetScrollRange(Wnd, SB_CTL, (LPINT) wParam, (LPINT) lParam); case SBM_ENABLE_ARROWS: return EnableScrollBar(Wnd, SB_CTL, wParam); case SBM_SETSCROLLINFO: return NtUserSetScrollInfo(Wnd, SB_CTL, (SCROLLINFO *) lParam, wParam); case SBM_GETSCROLLINFO: return NtUserSBGetParms(Wnd, SB_CTL, NULL, (SCROLLINFO *) lParam); case SBM_GETSCROLLBARINFO: ((PSCROLLBARINFO)lParam)->cbSize = sizeof(SCROLLBARINFO); return NtUserGetScrollBarInfo(Wnd, OBJID_CLIENT, (PSCROLLBARINFO)lParam); case 0x00e5: case 0x00e7: case 0x00e8: case 0x00ec: case 0x00ed: case 0x00ee: case 0x00ef: WARN("unknown Win32 msg %04x wp=%08lx lp=%08lx\n", Msg, wParam, lParam ); break; default: if (WM_USER <= Msg) { WARN("unknown msg %04x wp=%04lx lp=%08lx\n", Msg, wParam, lParam); } return DefWindowProc(Wnd, Msg, wParam, lParam ); } return 0; }
/*********************************************************************** * IntScrollHandleScrollEvent * * Handle a mouse or timer event for the scrollbar. * 'Pt' is the location of the mouse event in drawing coordinates */ static VOID FASTCALL IntScrollHandleScrollEvent(HWND Wnd, INT SBType, UINT Msg, POINT Pt) { static POINT PrevPt; /* Previous mouse position for timer events */ static UINT TrackThumbPos; /* Thumb position when tracking started. */ static INT LastClickPos; /* Position in the scroll-bar of the last button-down event. */ static INT LastMousePos; /* Position in the scroll-bar of the last mouse event. */ DWORD HitTest; HWND WndOwner, WndCtl; BOOL Vertical; HDC Dc; SCROLLBARINFO ScrollBarInfo; SETSCROLLBARINFO NewInfo; if (! IntGetScrollBarInfo(Wnd, SBType, &ScrollBarInfo)) { return; } if (SCROLL_NOWHERE == ScrollTrackHitTest && WM_LBUTTONDOWN != Msg) { return; } NewInfo.nTrackPos = ScrollTrackingVal; NewInfo.reserved = ScrollBarInfo.reserved; memcpy(NewInfo.rgstate, ScrollBarInfo.rgstate, (CCHILDREN_SCROLLBAR + 1) * sizeof(DWORD)); if (SB_CTL == SBType && 0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & (SBS_SIZEGRIP | SBS_SIZEBOX))) { switch(Msg) { case WM_LBUTTONDOWN: /* Initialise mouse tracking */ HideCaret(Wnd); /* hide caret while holding down LBUTTON */ SetCapture(Wnd); PrevPt = Pt; ScrollTrackHitTest = HitTest = SCROLL_THUMB; break; case WM_MOUSEMOVE: GetClientRect(GetParent(GetParent(Wnd)), &ScrollBarInfo.rcScrollBar); PrevPt = Pt; break; case WM_LBUTTONUP: ReleaseCapture(); ScrollTrackHitTest = HitTest = SCROLL_NOWHERE; if (Wnd == GetFocus()) { ShowCaret(Wnd); } break; case WM_SYSTIMER: Pt = PrevPt; break; } return; } Dc = GetDCEx(Wnd, 0, DCX_CACHE | ((SB_CTL == SBType) ? 0 : DCX_WINDOW)); if (SB_VERT == SBType) { Vertical = TRUE; } else if (SB_HORZ == SBType) { Vertical = FALSE; } else { Vertical = (0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & SBS_VERT)); } WndOwner = (SB_CTL == SBType) ? GetParent(Wnd) : Wnd; WndCtl = (SB_CTL == SBType) ? Wnd : NULL; switch (Msg) { case WM_LBUTTONDOWN: /* Initialise mouse tracking */ HideCaret(Wnd); /* hide caret while holding down LBUTTON */ ScrollTrackVertical = Vertical; ScrollTrackHitTest = HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, FALSE ); LastClickPos = Vertical ? (Pt.y - ScrollBarInfo.rcScrollBar.top) : (Pt.x - ScrollBarInfo.rcScrollBar.left); LastMousePos = LastClickPos; TrackThumbPos = ScrollBarInfo.xyThumbTop; PrevPt = Pt; if (SB_CTL == SBType && 0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & WS_TABSTOP)) { SetFocus(Wnd); } SetCapture(Wnd); ScrollBarInfo.rgstate[ScrollTrackHitTest] |= STATE_SYSTEM_PRESSED; NewInfo.rgstate[ScrollTrackHitTest] = ScrollBarInfo.rgstate[ScrollTrackHitTest]; NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo); break; case WM_MOUSEMOVE: HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, TRUE); PrevPt = Pt; break; case WM_LBUTTONUP: HitTest = SCROLL_NOWHERE; ReleaseCapture(); /* if scrollbar has focus, show back caret */ if (Wnd == GetFocus()) { ShowCaret(Wnd); } ScrollBarInfo.rgstate[ScrollTrackHitTest] &= ~STATE_SYSTEM_PRESSED; NewInfo.rgstate[ScrollTrackHitTest] = ScrollBarInfo.rgstate[ScrollTrackHitTest]; NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo); break; case WM_SYSTIMER: Pt = PrevPt; HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, FALSE); break; default: return; /* Should never happen */ } switch (ScrollTrackHitTest) { case SCROLL_NOWHERE: /* No tracking in progress */ break; case SCROLL_TOP_ARROW: if (HitTest == ScrollTrackHitTest) { if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg)) { SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_LINEUP, (LPARAM) WndCtl); } SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, (TIMERPROC) NULL); } else { KillSystemTimer(Wnd, SCROLL_TIMER); } break; case SCROLL_TOP_RECT: if (HitTest == ScrollTrackHitTest) { if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg)) { SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_PAGEUP, (LPARAM) WndCtl); } SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, (TIMERPROC) NULL); } else { KillSystemTimer(Wnd, SCROLL_TIMER); } break; case SCROLL_THUMB: if (WM_LBUTTONDOWN == Msg) { ScrollTrackingWin = Wnd; ScrollTrackingBar = SBType; ScrollTrackingPos = TrackThumbPos + LastMousePos - LastClickPos; ScrollTrackingVal = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical, ScrollTrackingPos); NewInfo.nTrackPos = ScrollTrackingVal; NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo); IntScrollDrawMovingThumb(Dc, &ScrollBarInfo, Vertical); } else if (WM_LBUTTONUP == Msg) { ScrollTrackingWin = 0; ScrollTrackingVal = 0; IntDrawScrollInterior(Wnd, Dc, SBType, Vertical, &ScrollBarInfo); } else /* WM_MOUSEMOVE */ { UINT Pos; if (! IntScrollPtInRectEx(&ScrollBarInfo.rcScrollBar, Pt, Vertical)) { Pos = LastClickPos; } else { Pt = IntScrollClipPos(&ScrollBarInfo.rcScrollBar, Pt); Pos = Vertical ? (Pt.y - ScrollBarInfo.rcScrollBar.top) : (Pt.x - ScrollBarInfo.rcScrollBar.left); } if (Pos != LastMousePos || ! ScrollMovingThumb) { LastMousePos = Pos; ScrollTrackingPos = TrackThumbPos + Pos - LastClickPos; ScrollTrackingVal = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical, ScrollTrackingPos); NewInfo.nTrackPos = ScrollTrackingVal; NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo); IntScrollDrawMovingThumb(Dc, &ScrollBarInfo, Vertical); SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, ScrollTrackingVal), (LPARAM) WndCtl); } } break; case SCROLL_BOTTOM_RECT: if (HitTest == ScrollTrackHitTest) { if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg)) { SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_PAGEDOWN, (LPARAM) WndCtl); } SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, (TIMERPROC) NULL); } else { KillSystemTimer(Wnd, SCROLL_TIMER); } break; case SCROLL_BOTTOM_ARROW: if (HitTest == ScrollTrackHitTest) { if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg)) { SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_LINEDOWN, (LPARAM) WndCtl); } SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, (TIMERPROC) NULL); } else { KillSystemTimer(Wnd, SCROLL_TIMER); } break; } if (WM_LBUTTONDOWN == Msg) { if (SCROLL_THUMB == HitTest) { UINT Val = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical, TrackThumbPos + LastMousePos - LastClickPos); SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, Val), (LPARAM) WndCtl); } } if (WM_LBUTTONUP == Msg) { HitTest = ScrollTrackHitTest; ScrollTrackHitTest = SCROLL_NOWHERE; /* Terminate tracking */ if (SCROLL_THUMB == HitTest) { UINT Val = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical, TrackThumbPos + LastMousePos - LastClickPos); SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, Val), (LPARAM) WndCtl); } SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL, SB_ENDSCROLL, (LPARAM) WndCtl); } ReleaseDC(Wnd, Dc); }
/*! * \param hwnd handle to window * \param uMsg message identifier * \param wParam first message parameter * \param lParam second message parameter */ LRESULT CALLBACK BlueWindow::SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Obtain the original window procedure, before subclassing. WNDPROC lpfnOldWindowProc = NULL; hwndprocmap_t::const_iterator lpfnit = OldWindowProcs.find(hwnd); if (lpfnit != OldWindowProcs.end()) { lpfnOldWindowProc = lpfnit->second; } else { DOUT(("BlueWindow::SubclassProc called for unknown window %p. Ignoring.\n", (void*) hwnd)); return DefWindowProc(hwnd, uMsg, wParam, lParam); } // Start handling the special messages. if (uMsg == WM_NCPAINT) { // First let the original method do its work. LRESULT lResult = CallWindowProc(lpfnOldWindowProc, hwnd, uMsg, wParam, lParam); // Now overpaint the border with a blue line. HDC hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN); if (!hdc) { // If GetDCEx() failed, then try again with just GetWindowDC(). hdc = GetWindowDC(hwnd); } if (hdc) { RECT windowrect, workrect; GetWindowRect(hwnd, &windowrect); HBRUSH hBlueBrush = CreateSolidBrush(RGB(0,0,255)); const int framewidth = GetSystemMetrics(SM_CXSIZEFRAME); const int frameheight = GetSystemMetrics(SM_CYSIZEFRAME); // draw the top border. workrect.top = 0; workrect.left = 0; workrect.right = windowrect.right - windowrect.left; workrect.bottom = frameheight; FillRect(hdc, &workrect, hBlueBrush); // draw the left border. workrect.top = 0; workrect.left = 0; workrect.right = framewidth; workrect.bottom = windowrect.bottom - windowrect.top; FillRect(hdc, &workrect, hBlueBrush); // draw the right border. workrect.top = 0; workrect.left = windowrect.right - windowrect.left - framewidth; workrect.right = windowrect.right - windowrect.left; workrect.bottom = windowrect.bottom - windowrect.top; FillRect(hdc, &workrect, hBlueBrush); // draw the bottom border. workrect.top = windowrect.bottom - windowrect.top - frameheight; workrect.left = 0; workrect.right = windowrect.right - windowrect.left; workrect.bottom = windowrect.bottom - windowrect.top; FillRect(hdc, &workrect, hBlueBrush); //HPEN hBluePenWidth = CreatePen(PS_INSIDEFRAME, framewidth, RGB(0,0,255)); //HPEN hBluePenHeight = CreatePen(PS_INSIDEFRAME, frameheight, RGB(0,0,255)); //Rectangle(hdc, windowrect.left, windowrect.top, windowrect.right, windowrect.bottom); DeleteObject(hBlueBrush); ReleaseDC(hwnd, hdc); } // Return the original result code. return lResult; } else if (uMsg == WM_DESTROY) { // Window is about to be destroyed, so remove the subclassing. SetWindowLongPtr(hwnd, GWL_WNDPROC, PtrToLong(lpfnOldWindowProc)); OldWindowProcs.erase(hwnd); return CallWindowProc(lpfnOldWindowProc, hwnd, uMsg, wParam, lParam); } else { // Otherwise let the normal window proc handle it. return CallWindowProc(lpfnOldWindowProc, hwnd, uMsg, wParam, lParam); } }
/* Helper function that blits the front buffer contents to the target window. */ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) { const struct wined3d_surface *front; POINT offset = {0, 0}; HDC src_dc, dst_dc; RECT draw_rect; HWND window; TRACE("swapchain %p, rect %s.\n", swapchain, wine_dbgstr_rect(rect)); front = swapchain->front_buffer; if (!(front->resource.usage & WINED3DUSAGE_RENDERTARGET)) return; TRACE("Copying surface %p to screen.\n", front); src_dc = front->hDC; window = swapchain->win_handle; dst_dc = GetDCEx(window, 0, DCX_CLIPSIBLINGS | DCX_CACHE); /* Front buffer coordinates are screen coordinates. Map them to the * destination window if not fullscreened. */ if (swapchain->presentParms.Windowed) ClientToScreen(window, &offset); TRACE("offset %s.\n", wine_dbgstr_point(&offset)); #if 0 /* FIXME: This doesn't work... if users really want to run * X in 8bpp, then we need to call directly into display.drv * (or Wine's equivalent), and force a private colormap * without default entries. */ if (front->palette) { SelectPalette(dst_dc, front->palette->hpal, FALSE); RealizePalette(dst_dc); /* sends messages => deadlocks */ } #endif draw_rect.left = 0; draw_rect.right = front->resource.width; draw_rect.top = 0; draw_rect.bottom = front->resource.height; #if 0 /* TODO: Support clippers. */ if (front->clipper) { RECT xrc; HWND hwnd = front->clipper->hWnd; if (hwnd && GetClientRect(hwnd,&xrc)) { OffsetRect(&xrc, offset.x, offset.y); IntersectRect(&draw_rect, &draw_rect, &xrc); } } #endif if (!rect) { /* Only use this if the caller did not pass a rectangle, since * due to double locking this could be the wrong one... */ if (front->lockedRect.left != front->lockedRect.right) IntersectRect(&draw_rect, &draw_rect, &front->lockedRect); } else { IntersectRect(&draw_rect, &draw_rect, rect); } BitBlt(dst_dc, draw_rect.left - offset.x, draw_rect.top - offset.y, draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top, src_dc, draw_rect.left, draw_rect.top, SRCCOPY); ReleaseDC(window, dst_dc); }
/* * FIXME: * - Drawing of WS_BORDER after scrollbars * - Correct drawing of size-box */ LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active) { HDC hDC; DWORD Style, ExStyle; HWND Parent; RECT ClientRect, WindowRect, CurrentRect, TempRect; if (!IsWindowVisible(hWnd)) return 0; Style = GetWindowLongPtrW(hWnd, GWL_STYLE); hDC = GetDCEx(hWnd, hRgn, DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN); if (hDC == 0) { return 0; } Parent = GetParent(hWnd); ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE); if (Active == -1) { if (ExStyle & WS_EX_MDICHILD) { Active = IsChild(GetForegroundWindow(), hWnd); if (Active) Active = (hWnd == (HWND)SendMessageW(Parent, WM_MDIGETACTIVE, 0, 0)); } else { Active = (GetForegroundWindow() == hWnd); } } GetWindowRect(hWnd, &WindowRect); GetClientRect(hWnd, &ClientRect); CurrentRect.top = CurrentRect.left = 0; CurrentRect.right = WindowRect.right - WindowRect.left; CurrentRect.bottom = WindowRect.bottom - WindowRect.top; /* Draw outer edge */ if (UserHasWindowEdge(Style, ExStyle)) { DrawEdge(hDC, &CurrentRect, EDGE_RAISED, BF_RECT | BF_ADJUST); } else if (ExStyle & WS_EX_STATICEDGE) { #if 0 DrawEdge(hDC, &CurrentRect, BDR_SUNKENINNER, BF_RECT | BF_ADJUST | BF_FLAT); #else SelectObject(hDC, GetSysColorBrush(COLOR_BTNSHADOW)); PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, 1, PATCOPY); PatBlt(hDC, CurrentRect.left, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY); SelectObject(hDC, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, 1, PATCOPY); PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY); InflateRect(&CurrentRect, -1, -1); #endif } /* Firstly the "thick" frame */ if ((Style & WS_THICKFRAME) && !(Style & WS_MINIMIZE)) { LONG Width = (GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME)) * GetSystemMetrics(SM_CXBORDER); LONG Height = (GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME)) * GetSystemMetrics(SM_CYBORDER); SelectObject(hDC, GetSysColorBrush(Active ? COLOR_ACTIVEBORDER : COLOR_INACTIVEBORDER)); /* Draw frame */ PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, Height, PATCOPY); PatBlt(hDC, CurrentRect.left, CurrentRect.top, Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #ifdef __REACTOS__ PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #else PatBlt(hDC, CurrentRect.left, CurrentRect.bottom, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); PatBlt(hDC, CurrentRect.right, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #endif InflateRect(&CurrentRect, -Width, -Height); } /* Now the other bit of the frame */ if (Style & (WS_DLGFRAME | WS_BORDER) || ExStyle & WS_EX_DLGMODALFRAME) { DWORD Width = GetSystemMetrics(SM_CXBORDER); DWORD Height = GetSystemMetrics(SM_CYBORDER); SelectObject(hDC, GetSysColorBrush( (ExStyle & (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE)) ? COLOR_3DFACE : (ExStyle & WS_EX_STATICEDGE) ? COLOR_WINDOWFRAME : (Style & (WS_DLGFRAME | WS_THICKFRAME)) ? COLOR_3DFACE : COLOR_WINDOWFRAME)); /* Draw frame */ PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, Height, PATCOPY); PatBlt(hDC, CurrentRect.left, CurrentRect.top, Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #ifdef __REACTOS__ PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #else PatBlt(hDC, CurrentRect.left, CurrentRect.bottom, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); PatBlt(hDC, CurrentRect.right, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); #endif InflateRect(&CurrentRect, -Width, -Height); } /* Draw caption */ if ((Style & WS_CAPTION) == WS_CAPTION) { DWORD CaptionFlags = DC_ICON | DC_TEXT | DC_BUTTONS; HPEN PreviousPen; BOOL Gradient = FALSE; if(SystemParametersInfoW(SPI_GETGRADIENTCAPTIONS, 0, &Gradient, 0) && Gradient) { CaptionFlags |= DC_GRADIENT; } TempRect = CurrentRect; if (Active) { CaptionFlags |= DC_ACTIVE; } if (ExStyle & WS_EX_TOOLWINDOW) { CaptionFlags |= DC_SMALLCAP; TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSMCAPTION) - 1; CurrentRect.top += GetSystemMetrics(SM_CYSMCAPTION); } else { TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYCAPTION) - 1; CurrentRect.top += GetSystemMetrics(SM_CYCAPTION); } NtUserDrawCaption(hWnd, hDC, &TempRect, CaptionFlags); /* Draw buttons */ if (Style & WS_SYSMENU) { UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE); if ((Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(ExStyle & WS_EX_TOOLWINDOW)) { UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMIN); UserDrawCaptionButton(hWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMAX); } } if(!(Style & WS_MINIMIZE)) { /* Line under caption */ PreviousPen = SelectObject(hDC, GetStockObject(DC_PEN)); SetDCPenColor(hDC, GetSysColor( ((ExStyle & (WS_EX_STATICEDGE | WS_EX_CLIENTEDGE | WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ? COLOR_WINDOWFRAME : COLOR_3DFACE)); MoveToEx(hDC, TempRect.left, TempRect.bottom, NULL); LineTo(hDC, TempRect.right, TempRect.bottom); SelectObject(hDC, PreviousPen); } } if(!(Style & WS_MINIMIZE)) { HMENU menu = GetMenu(hWnd); /* Draw menu bar */ if (menu && !(Style & WS_CHILD)) { TempRect = CurrentRect; TempRect.bottom = TempRect.top + (UINT)NtUserxSetMenuBarHeight(menu, 0); CurrentRect.top += MenuDrawMenuBar(hDC, &TempRect, hWnd, FALSE); } if (ExStyle & WS_EX_CLIENTEDGE) { DrawEdge(hDC, &CurrentRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); } /* Draw the scrollbars */ if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL) && IntIsScrollBarVisible(hWnd, OBJID_VSCROLL) && IntIsScrollBarVisible(hWnd, OBJID_HSCROLL)) { RECT ParentClientRect; TempRect = CurrentRect; if (ExStyle & WS_EX_LEFTSCROLLBAR) TempRect.right = TempRect.left + GetSystemMetrics(SM_CXVSCROLL); else TempRect.left = TempRect.right - GetSystemMetrics(SM_CXVSCROLL); TempRect.top = TempRect.bottom - GetSystemMetrics(SM_CYHSCROLL); FillRect(hDC, &TempRect, GetSysColorBrush(COLOR_BTNFACE)); /* FIXME: Correct drawing of size-box with WS_EX_LEFTSCROLLBAR */ if(Parent) GetClientRect(Parent, &ParentClientRect); if (HASSIZEGRIP(Style, ExStyle, GetWindowLongPtrW(Parent, GWL_STYLE), WindowRect, ParentClientRect)) { DrawFrameControl(hDC, &TempRect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); } IntDrawScrollBar(hWnd, hDC, SB_VERT); IntDrawScrollBar(hWnd, hDC, SB_HORZ); } else { if (Style & WS_VSCROLL && IntIsScrollBarVisible(hWnd, OBJID_VSCROLL)) IntDrawScrollBar(hWnd, hDC, SB_VERT); else if (Style & WS_HSCROLL && IntIsScrollBarVisible(hWnd, OBJID_HSCROLL)) IntDrawScrollBar(hWnd, hDC, SB_HORZ); } } ReleaseDC(hWnd, hDC); if (hRgn != HRGN_WINDOW) DeleteObject(hRgn); // We use DCX_KEEPCLIPRGN return 0; // For WM_NCPAINT message, return 0. }
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPInst, PSTR szCmd, int iShow) { Nods.hHeap = GetProcessHeap(); if (Nods.hHeap == NULL) repquit("Process memory error"); signal(SIGINT, repsig); signal(SIGTERM, repsig); signal(SIGSEGV, repsig); InvalidateRect(0, 0, WM_ERASEBKGND); Nods.hwnd = GetDesktopWindow(); const int waw = GetSystemMetrics(SM_CXSCREEN), wah = GetSystemMetrics(SM_CYSCREEN); Nods.source = GetDCEx(Nods.hwnd, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE | DCX_CLIPCHILDREN); mknods(waw, wah); const int wah2 = Nods.nod_sum; /* wah shrunk */ Nods.context = CreateCompatibleDC(Nods.source); nod in, /* plitka index */ ips; /* plitka size */ int xpos, ypos; MSG msg; RECT Rect; unsigned char r, g, b, stdev; unsigned char const threshold = 15; HBRUSH hBrush; while (1) { if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else { Sleep(5); in = Nods.nods_uniform[rand() % Nods.nod_sum_uniform]; ips = Nods.nods[in]; xpos = rand()%waw; xpos = xpos - xpos % ips; ypos = Nods.plitka_offset[in]; SetRect(&Rect, xpos, ypos + (wah - wah2), xpos + ips - 1, ypos + ips + (wah - wah2) - 1); do { r = 0x55 + rand()%0xaa; g = 0x55 + rand()%0xaa; b = 0x55 + rand()%0xaa; stdev = (r + g + b) / 3; } while ( abs(r - stdev) <= threshold || abs(g - stdev) <= threshold || abs(b - stdev) <= threshold ); hBrush = CreateSolidBrush(RGB(r, g, b)); FillRect(Nods.source, &Rect, hBrush); DeleteObject(hBrush); } } DeleteDC(Nods.context); DeleteDC(Nods.source); ReleaseDC(Nods.hwnd, Nods.source); xfree(Nods.nods); xfree(Nods.nods_uniform); xfree(Nods.plitka_offset); return 0; }
/* * This procedure implements the messages passed by the window * manager for default processing on behalf of the window. */ LRESULT WINAPI DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; RECT rc; DWORD dwStyle; HBRUSH hbr; HPEN hpen, holdpen; PAINTSTRUCT ps; POINT curpt; int x, y; HWND wp; HWND oldActive; COLORREF crCaption; LPNCCALCSIZE_PARAMS lpnc; CHAR szTitle[64]; static POINT startpt; switch(msg) { case WM_NCCALCSIZE: /* calculate client rect from passed window rect in rgrc[0]*/ lpnc = (LPNCCALCSIZE_PARAMS)lParam; dwStyle = GetWindowLong(hwnd, GWL_STYLE); if(dwStyle & WS_BORDER) { if((dwStyle & WS_CAPTION) == WS_CAPTION) { InflateRect(&lpnc->rgrc[0], -mwSYSMETRICS_CXFRAME, -mwSYSMETRICS_CYFRAME); lpnc->rgrc[0].top += mwSYSMETRICS_CYCAPTION + 1; } else InflateRect(&lpnc->rgrc[0], -1, -1); } break; case WM_NCPAINT: /* repaint all non-client area*/ dwStyle = GetWindowLong(hwnd, GWL_STYLE); if(dwStyle & WS_BORDER) { hdc = GetWindowDC(hwnd); GetWindowRect(hwnd, &rc); if((dwStyle & WS_CAPTION) == WS_CAPTION) { /* draw 2-line 3d border around window*/ Draw3dOutset(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top); InflateRect(&rc, -2, -2); /* draw 1-line inset inside border*/ hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNFACE)); holdpen = SelectObject(hdc, hpen); SelectObject(hdc, GetStockObject(NULL_BRUSH)); Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); InflateRect(&rc, -1, -1); /* fill caption*/ rc.bottom = rc.top + mwSYSMETRICS_CYCAPTION; crCaption = GetActiveWindow()==hwnd? GetSysColor(COLOR_ACTIVECAPTION): GetSysColor(COLOR_INACTIVECAPTION); hbr = CreateSolidBrush(crCaption); FillRect(hdc, &rc, hbr); DeleteObject(hbr); /* draw 1 line under caption*/ MoveToEx(hdc, rc.left, rc.bottom, NULL); LineTo(hdc, rc.right, rc.bottom); DeleteObject(SelectObject(hdc, holdpen)); /* draw caption text*/ if(GetWindowText(hwnd, szTitle, sizeof(szTitle))) { SetBkMode(hdc, TRANSPARENT); /* set background color even though * transparent in case GdArea is used * to draw text which compares * gr_foreground != gr_background * when transparent... */ SetBkColor(hdc, crCaption); SetTextColor(hdc, GetActiveWindow()==hwnd? GetSysColor(COLOR_CAPTIONTEXT): GetSysColor(COLOR_INACTIVECAPTIONTEXT)); SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); GetWindowRect(hwnd, &rc); TextOut(hdc, rc.left+4, rc.top+2, szTitle, strlen(szTitle)); } /* draw close box*/ GetCloseBoxRect(hwnd, &rc); /*DrawDIB(hdc, rc.right-XSIZE_CLOSEBOX-3, rc.top+3, &image_close4);*/ Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_WINDOWFRAME)); InflateRect(&rc, -1, -1); hbr = CreateSolidBrush( GetSysColor(COLOR_BTNFACE)); FillRect(hdc, &rc, hbr); DeleteObject(hbr); InflateRect(&rc, -1, -1); MoveToEx(hdc, rc.left, rc.top, NULL); LineTo(hdc, rc.right-1, rc.bottom-1); MoveToEx(hdc, rc.left, rc.bottom-1, NULL); LineTo(hdc, rc.right-1, rc.top); } else { SelectObject(hdc, GetStockObject(NULL_BRUSH)); Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); } ReleaseDC(hwnd, hdc); } break; case WM_NCHITTEST: /* if system is dragging a window, always return caption*/ if(dragwp) return HTCAPTION; /* Determine what part of the window the mouse is over*/ POINTSTOPOINT(curpt, lParam); if(PtInRect(&hwnd->clirect, curpt)) return HTCLIENT; if(PtInRect(&hwnd->vscroll.rc, curpt)) return HTVSCROLL; if(PtInRect(&hwnd->hscroll.rc, curpt)) return HTHSCROLL; dwStyle = GetWindowLong(hwnd, GWL_STYLE); if((dwStyle & WS_CAPTION) == WS_CAPTION) { GetCloseBoxRect(hwnd, &rc); if(PtInRect(&rc, curpt)) return HTCLOSE; GetWindowRect(hwnd, &rc); InflateRect(&rc, -2, -2); rc.bottom = rc.top + mwSYSMETRICS_CYCAPTION; if(PtInRect(&rc, curpt)) return HTCAPTION; GetWindowRect(hwnd, &rc); InflateRect(&rc, -2, -2); rc.top += mwSYSMETRICS_CYCAPTION; if(PtInRect(&rc, curpt)) return HTCLIENT; return HTBORDER; } return HTNOWHERE; case WM_NCLBUTTONDOWN: /* Handle default actions for mouse down on window*/ if(wParam == HTCLOSE) { SendMessage(hwnd, WM_CLOSE, 0, 0L); break; } /* set focus on mouse down, repaint if necessary*/ oldActive = GetActiveWindow(); if(wParam == HTCLIENT || wParam == HTVSCROLL || wParam == HTHSCROLL) /* activate and raise window if in client area*/ /* kaffe port requires this commented out*/ SetForegroundWindow(hwnd); else { /* otherwise just change focus window, same z order*/ /* this will activate it's top level parent*/ SetFocus(hwnd); } /* repaint captions now because of activation change*/ UpdateWindow(oldActive); UpdateWindow(hwnd); if(wParam == HTVSCROLL || wParam == HTHSCROLL) { MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam); break; } /* start window drag if in caption area*/ if(wParam == HTCAPTION && hwnd != rootwp) { POINTSTOPOINT(startpt, lParam); if(!(GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZE)) dragwp = hwnd; SetRectEmpty(&lastrc); /* XORMOVE only*/ } break; case WM_NCMOUSEMOVE: if(wParam == HTVSCROLL || wParam == HTHSCROLL) { MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam); break; } /* drag window with mousemove after mousedown*/ if(dragwp == hwnd) { POINTSTOPOINT(curpt, lParam); x = curpt.x - startpt.x; y = curpt.y - startpt.y; if(mwERASEMOVE) { GetWindowRect(hwnd, &rc); MoveWindow(hwnd, rc.left+x, rc.top+y, rc.right-rc.left, rc.bottom-rc.top, TRUE); startpt = curpt; } else DrawXORFrame(hwnd, x, y, TRUE); } break; case WM_NCLBUTTONUP: /* stop window drag*/ if(dragwp == hwnd) { dragwp = NULL; if(mwERASEMOVE) { /* * User stopped moving window, repaint * windows previously queued for painting. */ for(wp=listwp; wp; wp=wp->next) if(wp->gotPaintMsg == PAINT_DELAYPAINT) wp->gotPaintMsg = PAINT_NEEDSPAINT; } else { POINTSTOPOINT(curpt, lParam); x = curpt.x - startpt.x; y = curpt.y - startpt.y; DrawXORFrame(hwnd, x, y, FALSE); GetWindowRect(hwnd, &rc); MoveWindow(hwnd, rc.left+x, rc.top+y, rc.right-rc.left, rc.bottom-rc.top, TRUE); } } if(wParam == HTVSCROLL || wParam == HTHSCROLL) { MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam); break; } break; case WM_NCLBUTTONDBLCLK: if(wParam == HTVSCROLL || wParam == HTHSCROLL) { MwHandleNCMessageScrollbar(hwnd, msg, wParam, lParam); break; } /* maximize/restore processing*/ if(wParam != HTCAPTION) break; if((hwnd->style & WS_CAPTION) == WS_CAPTION) { if(hwnd->style & WS_MAXIMIZE) { rc = hwnd->restorerc; MoveWindow(hwnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE); hwnd->style &= ~WS_MAXIMIZE; } else { hwnd->restorerc = hwnd->winrect; GetWindowRect(rootwp, &rc); MoveWindow(hwnd, -mwSYSMETRICS_CXFRAME, -mwSYSMETRICS_CYFRAME, rc.right+2*mwSYSMETRICS_CXFRAME, rc.bottom+2*mwSYSMETRICS_CYFRAME, TRUE); hwnd->style |= WS_MAXIMIZE; } } break; case WM_GETTEXTLENGTH: /* Get window text length. This routine requires * knowledge of the internal window structure */ return strlen(hwnd->szTitle); case WM_GETTEXT: /* Get window text. This routine requires * knowledge of the internal window structure */ return strzcpy((LPSTR)lParam, hwnd->szTitle, wParam); case WM_SETTEXT: /* Set window text. This routine requires * knowledge of the internal window structure. * Note that setting text doesn't invalidate the window. */ strzcpy(hwnd->szTitle, (LPSTR)lParam, sizeof(hwnd->szTitle)); return TRUE; case WM_CLOSE: DestroyWindow(hwnd); if(hwnd == rootwp) PostQuitMessage(0); break; case WM_ERASEBKGND: /* erase background with class background brush*/ hbr = (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND); if(!hbr) return 0; /* don't exclude update region*/ hdc = GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP); FillRect(hdc, NULL, hbr); ReleaseDC(hwnd, hdc); return 1; case WM_PAINT: /* required to send erasebkgnd for desktop window*/ hdc = BeginPaint(hwnd, &ps); /* draw desktop wallpaper*/ if(hwnd == rootwp && pImageWallpaper) { GetWindowRect(hwnd, &rc); DrawDIB(hdc, (rc.right-rc.left-pImageWallpaper->width)/2, (rc.bottom-rc.top-pImageWallpaper->height)/2, pImageWallpaper); } EndPaint(hwnd, &ps); break; } return 0; }