void UIMachineWindowSeamless::setMask(const QRegion &constRegion) { /* Could be unused under Mac: */ Q_UNUSED(constRegion); #ifndef Q_WS_MAC /* Copy mask: */ QRegion region = constRegion; /* Shift region if left spacer width is NOT zero or top spacer height is NOT zero: */ if (m_pLeftSpacer->geometry().width() || m_pTopSpacer->geometry().height()) region.translate(m_pLeftSpacer->geometry().width(), m_pTopSpacer->geometry().height()); /* Take into account mini tool-bar region: */ if (m_pMiniToolBar) { /* Move mini-toolbar region to mini-toolbar position: */ QRegion toolBarRegion(m_pMiniToolBar->rect()); toolBarRegion.translate(QPoint(m_pMiniToolBar->x(), m_pMiniToolBar->y())); /* Include mini-toolbar region into common one: */ region += toolBarRegion; } #endif /* !Q_WS_MAC */ #if defined (Q_WS_WIN) # if 0 /* This code is disabled for a long time already, need analisys... */ QRegion difference = m_prevRegion.subtract(region); /* Region offset calculation */ int fleft = 0, ftop = 0; /* Visible region calculation */ HRGN newReg = CreateRectRgn(0, 0, 0, 0); CombineRgn(newReg, region.handle(), 0, RGN_COPY); OffsetRgn(newReg, fleft, ftop); /* Invisible region calculation */ HRGN diffReg = CreateRectRgn(0, 0, 0, 0); CombineRgn(diffReg, difference.handle(), 0, RGN_COPY); OffsetRgn(diffReg, fleft, ftop); /* Set the current visible region and clean the previous */ SetWindowRgn(winId(), newReg, FALSE); RedrawWindow(0, 0, diffReg, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); if (machineView()) RedrawWindow(machineView()->viewport()->winId(), 0, 0, RDW_INVALIDATE); m_prevRegion = region; # endif /* This code is disabled for a long time already, need analisys... */ UIMachineWindow::setMask(region); #elif defined (Q_WS_MAC) # if defined (VBOX_GUI_USE_QUARTZ2D) if (vboxGlobal().vmRenderMode() == Quartz2DMode) { /* If we are using the Quartz2D backend we have to trigger a repaint only. * All the magic clipping stuff is done in the paint engine. */ ::darwinWindowInvalidateShape(m_pMachineView->viewport()); } # endif /* VBOX_GUI_USE_QUARTZ2D */ # if 0 /* This code is disabled for a long time already, need analisys... */ /* This is necessary to avoid the flicker by an mask update. * See http://lists.apple.com/archives/Carbon-development/2001/Apr/msg01651.html for the hint. * There *must* be a better solution. */ // if (!region.isEmpty()) // region |= QRect(0, 0, 1, 1); // /* Save the current region for later processing in the darwin event handler. */ // mCurrRegion = region; // /* We repaint the screen before the ReshapeCustomWindow command. Unfortunately // * this command flushes a copy of the backbuffer to the screen after the new // * mask is set. This leads into a misplaced drawing of the content. Currently // * no alternative to this and also this is not 100% perfect. */ // repaint(); // qApp->processEvents(); // /* Now force the reshaping of the window. This is definitely necessary. */ // ReshapeCustomWindow(reinterpret_cast<WindowPtr>(winId())); // UIMachineWindow::setMask(region); // HIWindowInvalidateShadow(::darwinToWindowRef(mConsole->viewport())); # endif /* This code is disabled for a long time already, need analisys... */ #else /* !Q_WS_MAC */ UIMachineWindow::setMask(region); #endif }
// Similar to DrawText win32 api function // Pass uFormat | DT_CALCRECT to calc rectangle to be returned by lpRect // parseInfo is optional (pass NULL and it will be calculated and deleted inside function int Smileys_DrawText(HDC hDC, LPCTSTR lpString, int nCount, LPRECT lpRect, UINT uFormat, const char *protocol, SmileysParseInfo parseInfo) { SmileysParseInfo info; int ret; if (nCount < 0) nCount = (int)mir_tstrlen(lpString); // Get parse info if (parseInfo == NULL) info = Smileys_PreParse(lpString, nCount, protocol); else info = parseInfo; if (uFormat & DT_CALCRECT) { SIZE text_size = GetTextSize(hDC, lpString, info->pieces, uFormat, info->max_height); lpRect->bottom = min(lpRect->bottom, lpRect->top + text_size.cy); if (text_size.cx < lpRect->right - lpRect->left) { if (uFormat & DT_RIGHT) lpRect->left = lpRect->right - text_size.cx; else lpRect->right = lpRect->left + text_size.cx; } ret = text_size.cy; } else { // Clipping rgn HRGN oldRgn = CreateRectRgn(0, 0, 1, 1); if (GetClipRgn(hDC, oldRgn) != 1) { DeleteObject(oldRgn); oldRgn = NULL; } HRGN rgn = CreateRectRgnIndirect(lpRect); ExtSelectClipRgn(hDC, rgn, RGN_AND); // Draw if (info->pieces == NULL) { ret = skin_DrawText(hDC, lpString, nCount, lpRect, uFormat); } else { RECT rc = *lpRect; SIZE text_size = GetTextSize(hDC, lpString, info->pieces, uFormat, info->max_height); if (text_size.cx < rc.right - rc.left) { if (uFormat & DT_RIGHT) rc.left = rc.right - text_size.cx; else rc.right = rc.left + text_size.cx; } ret = text_size.cy; DrawTextSmiley(hDC, rc, lpString, nCount, info->pieces, uFormat, info->max_height); } // Clipping rgn SelectClipRgn(hDC, oldRgn); DeleteObject(rgn); if (oldRgn) DeleteObject(oldRgn); } // Free parse info if (parseInfo == NULL) Smileys_FreeParse(info); return ret; }
HRGN CTaskbarNotifier::CreateRgnFromBitmap(HBITMAP hBmp, COLORREF color) { if (hBmp == NULL) return NULL; CDC* pDC = GetDC(); if (pDC == NULL) return NULL; BITMAP bm; GetObject(hBmp, sizeof(bm), &bm); ASSERT( !m_bBitmapAlpha ); const BYTE *pBitmapBits = NULL; if (bm.bmBitsPixel == 32 && m_pfnAlphaBlend) { DWORD dwBitmapBitsSize = GetBitmapBits(hBmp, 0, NULL); if (dwBitmapBitsSize) { pBitmapBits = (BYTE *)malloc(dwBitmapBitsSize); if (pBitmapBits) { if (GetBitmapBits(hBmp, dwBitmapBitsSize, (LPVOID)pBitmapBits) == (LONG)dwBitmapBitsSize) { const BYTE *pLine = pBitmapBits; int iLines = bm.bmHeight; while (!m_bBitmapAlpha && iLines-- > 0) { const DWORD *pdwPixel = (const DWORD *)pLine; for (int x = 0; x < bm.bmWidth; x++) { if (*pdwPixel++ & 0xFF000000) { m_bBitmapAlpha = true; break; } } pLine += bm.bmWidthBytes; } } if (!m_bBitmapAlpha) { free((void*)pBitmapBits); pBitmapBits = NULL; } } } } CDC dcBmp; dcBmp.CreateCompatibleDC(pDC); HGDIOBJ hOldBmp = dcBmp.SelectObject(hBmp); HRGN hRgn = NULL; // allocate memory for region data const DWORD MAXBUF = 40; // size of one block in RECTs (i.e. MAXBUF*sizeof(RECT) in bytes) DWORD cBlocks = 0; // number of allocated blocks RGNDATAHEADER *pRgnData = (RGNDATAHEADER *)calloc(sizeof(RGNDATAHEADER) + ++cBlocks * MAXBUF * sizeof(RECT), 1); if (pRgnData) { // fill it by default pRgnData->dwSize = sizeof(RGNDATAHEADER); pRgnData->iType = RDH_RECTANGLES; pRgnData->nCount = 0; INT iFirstXPos = 0; // left position of current scan line where mask was found bool bWasFirst = false; // set when mask was found in current scan line const BYTE *pBitmapLine = pBitmapBits != NULL ? pBitmapBits + bm.bmWidthBytes * (bm.bmHeight - 1) : NULL; for (int y = 0; pRgnData != NULL && y < bm.bmHeight; y++) { for (int x = 0; x < bm.bmWidth; x++) { // get color bool bIsMask; if (pBitmapLine) bIsMask = ((((const DWORD *)pBitmapLine)[x] & 0xFF000000) != 0x00000000); else bIsMask = (dcBmp.GetPixel(x, bm.bmHeight - y - 1) != color); // place part of scan line as RECT region if transparent color found after mask color or // mask color found at the end of mask image if (bWasFirst && ((bIsMask && (x == bm.bmWidth - 1)) || (bIsMask ^ (x < bm.bmWidth)))) { // get offset to RECT array if RGNDATA buffer LPRECT pRects = (LPRECT)(pRgnData + 1); // save current RECT pRects[pRgnData->nCount++] = CRect(iFirstXPos, bm.bmHeight - y - 1, x + (x == bm.bmWidth - 1), bm.bmHeight - y); // if buffer full reallocate it if (pRgnData->nCount >= cBlocks * MAXBUF) { RGNDATAHEADER *pNewRgnData = (RGNDATAHEADER *)realloc(pRgnData, sizeof(RGNDATAHEADER) + ++cBlocks * MAXBUF * sizeof(RECT)); if (pNewRgnData == NULL) { free(pRgnData); pRgnData = NULL; break; } pRgnData = pNewRgnData; } bWasFirst = false; } else if (!bWasFirst && bIsMask) { iFirstXPos = x; bWasFirst = true; } } if (pBitmapBits) pBitmapLine -= bm.bmWidthBytes; } if (pRgnData) { // Create region // WinNT: 'ExtCreateRegion' returns NULL (by [email protected]) hRgn = CreateRectRgn(0, 0, 0, 0); if (hRgn) { LPCRECT pRects = (LPRECT)(pRgnData + 1); for (DWORD i = 0; i < pRgnData->nCount; i++) { HRGN hr = CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom); VERIFY( CombineRgn(hRgn, hRgn, hr, RGN_OR) != ERROR ); if (hr) DeleteObject(hr); } } free(pRgnData); } } dcBmp.SelectObject(hOldBmp); dcBmp.DeleteDC(); free((void*)pBitmapBits); ReleaseDC(pDC); return hRgn; }
HRGN WinDiffRgn (HRGN hrgnSrc1, HRGN hrgnSrc2) { HRGN hrgnDest = CreateRectRgn(0, 0, 1, 1); CombineRgn(hrgnDest, hrgnSrc1, hrgnSrc2, RGN_DIFF); return hrgnDest; } /* WinDiffRgn */
// // InitWindowRegion // // We display the video in a window that has a region selected into it that // matches the word we are passed in. By doing this we let Windows manage // all the clipping and mouse technology. The trick is in creating a region // that matches the word, this is done by using paths. We create a path for // a temporary HDC, draw the word and then end the path. After which we can // then ask Windows for a region that describes that path. That gives us a // region for the outside of the word so we not it to get the word region // HRESULT CVideoText::InitWindowRegion(TCHAR *pStringName) { OSVERSIONINFO VersionInfo; VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); EXECUTE_ASSERT(GetVersionEx(&VersionInfo)); // Set a window region according to the OS capabilities if ((VersionInfo.dwPlatformId & VER_PLATFORM_WIN32_NT) == 0) { m_Size.cx = 320; m_Size.cy = 240; return NOERROR; } // Get the text extents the word passed in will require based on the // font and bitmap selected in the current device context. For it to // be displayed in a different font it must be selected into the HDC HDC hdc = CreateCompatibleDC(m_hdc); HFONT hFont = CreateVideoFont(); SelectObject(hdc,hFont); GetTextExtentPoint32((HDC) hdc, // The output device context pStringName, // The string we'll be using lstrlen(pStringName), // Number of characters in it (LPSIZE) &m_Size); // Filled in with the extents // Create a bitmap that matches the current format HBITMAP hMaskBitmap = CreateCompatibleBitmap(hdc,m_Size.cx,m_Size.cy); if (hMaskBitmap == NULL) { ASSERT(hMaskBitmap); return E_UNEXPECTED; } // Select the monochrome bitmap into the device context HBITMAP hBitmap = (HBITMAP) SelectObject(hdc,hMaskBitmap); EXECUTE_ASSERT(BeginPath(hdc)); // Draw the string into the monochrome bitmap ExtTextOut((HDC) hdc, // Target device context (int) 0, // x coordinate reference (int) 0, // Likewise y coordinate (DWORD) 0, // No special flags to set NULL, // No clipping rectangle pStringName, // Pointer to text words lstrlen(pStringName), // Number of characters NULL); // Intercharacter spacing EXECUTE_ASSERT(EndPath(hdc)); HRGN hOutside = PathToRegion(hdc); HRGN hFullWindow = CreateRectRgn(0,0,m_Size.cx,m_Size.cy); HRGN hWordRegion = CreateRectRgn(0,0,1,1); CombineRgn(hWordRegion,hFullWindow,hOutside,RGN_DIFF); SetWindowRgn(m_hwnd,hWordRegion,TRUE); // Clear up the regions we created DeleteObject(hWordRegion); DeleteObject(hOutside); DeleteObject(hFullWindow); // Delete the HDC and text bitmap SelectObject(hdc,hBitmap); HFONT hDefault = (HFONT) GetStockObject(SYSTEM_FONT); SelectObject(hdc,hDefault); DeleteObject(hFont); DeleteObject(hMaskBitmap); DeleteDC(hdc); return NOERROR; } // InitWindowRegion
void winShadowUpdateDDNL (ScreenPtr pScreen, shadowBufPtr pBuf) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RegionPtr damage = &pBuf->damage; HRESULT ddrval = DD_OK; RECT rcDest, rcSrc; POINT ptOrigin; DWORD dwBox = REGION_NUM_RECTS (damage); BoxPtr pBox = REGION_RECTS (damage); HRGN hrgnTemp = NULL, hrgnCombined = NULL; /* * Return immediately if the app is not active * and we are fullscreen, or if we have a bad display depth */ if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) || pScreenPriv->fBadDepth) return; /* Get the origin of the window in the screen coords */ ptOrigin.x = pScreenInfo->dwXOffset; ptOrigin.y = pScreenInfo->dwYOffset; MapWindowPoints (pScreenPriv->hwndScreen, HWND_DESKTOP, (LPPOINT)&ptOrigin, 1); /* * Handle small regions with multiple blits, * handle large regions by creating a clipping region and * doing a single blit constrained to that clipping region. */ if (pScreenInfo->dwClipUpdatesNBoxes == 0 || dwBox < pScreenInfo->dwClipUpdatesNBoxes) { /* Loop through all boxes in the damaged region */ while (dwBox--) { /* Assign damage box to source rectangle */ rcSrc.left = pBox->x1; rcSrc.top = pBox->y1; rcSrc.right = pBox->x2; rcSrc.bottom = pBox->y2; /* Calculate destination rectangle */ rcDest.left = ptOrigin.x + rcSrc.left; rcDest.top = ptOrigin.y + rcSrc.top; rcDest.right = ptOrigin.x + rcSrc.right; rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Blit the damaged areas */ ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, &rcDest, pScreenPriv->pddsShadow4, &rcSrc, DDBLT_WAIT, NULL); if (FAILED (ddrval)) { ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt () " "failed: %08x\n", ddrval); } /* Get a pointer to the next box */ ++pBox; } } else { BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); /* Compute a GDI region from the damaged region */ hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); dwBox--; pBox++; while (dwBox--) { hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); DeleteObject (hrgnTemp); pBox++; } /* Install the GDI region as a clipping region */ SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); DeleteObject (hrgnCombined); hrgnCombined = NULL; #if CYGDEBUG ErrorF ("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n", pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2, pBoxExtents->y2); #endif /* Calculating a bounding box for the source is easy */ rcSrc.left = pBoxExtents->x1; rcSrc.top = pBoxExtents->y1; rcSrc.right = pBoxExtents->x2; rcSrc.bottom = pBoxExtents->y2; /* Calculating a bounding box for the destination is trickier */ rcDest.left = ptOrigin.x + rcSrc.left; rcDest.top = ptOrigin.y + rcSrc.top; rcDest.right = ptOrigin.x + rcSrc.right; rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Our Blt should be clipped to the invalidated region */ ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, &rcDest, pScreenPriv->pddsShadow4, &rcSrc, DDBLT_WAIT, NULL); /* Reset the clip region */ SelectClipRgn (pScreenPriv->hdcScreen, NULL); } }
VOID ExtendSelection( IN PCONSOLE_INFORMATION Console, IN COORD CursorPosition ) /*++ This routine extends a selection region. --*/ { SMALL_RECT OldSelectionRect; HRGN OldRegion,NewRegion,CombineRegion; COORD FontSize; if (CursorPosition.X < 0) { CursorPosition.X = 0; } else if (CursorPosition.X >= Console->CurrentScreenBuffer->ScreenBufferSize.X) { CursorPosition.X = Console->CurrentScreenBuffer->ScreenBufferSize.X-1; } if (CursorPosition.Y < 0) { CursorPosition.Y = 0; } else if (CursorPosition.Y >= Console->CurrentScreenBuffer->ScreenBufferSize.Y) { CursorPosition.Y = Console->CurrentScreenBuffer->ScreenBufferSize.Y-1; } if (!(Console->SelectionFlags & CONSOLE_SELECTION_NOT_EMPTY)) { if (Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) { // scroll if necessary to make cursor visible. MakeCursorVisible(Console->CurrentScreenBuffer,CursorPosition); ASSERT(!(Console->SelectionFlags & CONSOLE_MOUSE_SELECTION)); // // if the selection rect hasn't actually been started, // the selection cursor is still blinking. turn it off. // ConsoleHideCursor(Console->CurrentScreenBuffer); } Console->SelectionFlags |= CONSOLE_SELECTION_NOT_EMPTY; Console->SelectionRect.Left =Console->SelectionRect.Right = Console->SelectionAnchor.X; Console->SelectionRect.Top = Console->SelectionRect.Bottom = Console->SelectionAnchor.Y; // invert the cursor corner if (Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) { MyInvert(Console,&Console->SelectionRect); } } else { if (Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) { // scroll if necessary to make cursor visible. MakeCursorVisible(Console->CurrentScreenBuffer,CursorPosition); } } // // update selection rect // OldSelectionRect = Console->SelectionRect; if (CursorPosition.X <= Console->SelectionAnchor.X) { Console->SelectionRect.Left = CursorPosition.X; Console->SelectionRect.Right = Console->SelectionAnchor.X; } else if (CursorPosition.X > Console->SelectionAnchor.X) { Console->SelectionRect.Right = CursorPosition.X; Console->SelectionRect.Left = Console->SelectionAnchor.X; } if (CursorPosition.Y <= Console->SelectionAnchor.Y) { Console->SelectionRect.Top = CursorPosition.Y; Console->SelectionRect.Bottom = Console->SelectionAnchor.Y; } else if (CursorPosition.Y > Console->SelectionAnchor.Y) { Console->SelectionRect.Bottom = CursorPosition.Y; Console->SelectionRect.Top = Console->SelectionAnchor.Y; } // // change inverted selection // if (Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) { FontSize = Console->CurrentScreenBuffer->BufferInfo.TextInfo.FontSize; } else { FontSize.X = 1; FontSize.Y = 1; } CombineRegion = CreateRectRgn(0,0,0,0); OldRegion = CreateRectRgn((OldSelectionRect.Left-Console->CurrentScreenBuffer->Window.Left)*FontSize.X, (OldSelectionRect.Top-Console->CurrentScreenBuffer->Window.Top)*FontSize.Y, (OldSelectionRect.Right-Console->CurrentScreenBuffer->Window.Left+1)*FontSize.X, (OldSelectionRect.Bottom-Console->CurrentScreenBuffer->Window.Top+1)*FontSize.Y ); NewRegion = CreateRectRgn((Console->SelectionRect.Left-Console->CurrentScreenBuffer->Window.Left)*FontSize.X, (Console->SelectionRect.Top-Console->CurrentScreenBuffer->Window.Top)*FontSize.Y, (Console->SelectionRect.Right-Console->CurrentScreenBuffer->Window.Left+1)*FontSize.X, (Console->SelectionRect.Bottom-Console->CurrentScreenBuffer->Window.Top+1)*FontSize.Y ); CombineRgn(CombineRegion,OldRegion,NewRegion,RGN_XOR); InvertRgn(Console->hDC,CombineRegion); DeleteObject(OldRegion); DeleteObject(NewRegion); DeleteObject(CombineRegion); }
void GifAvatar::draw(MyBitmap *bmp, int x, int y, int w, int h, POPUPOPTIONS *options) { if (!av || (w <= 0) || (h <= 0)) return; if (!frameCount || !frameDelays || !hBitmap || (cachedWidth != w) || (cachedHeight != h)) { cachedWidth = w; cachedHeight = h; if (frameDelays) { mir_free(frameDelays); frameDelays = NULL; } if (hBitmap) DeleteObject(hBitmap); GDIPlus_ExtractAnimatedGIF(av->szFilename, w, h, hBitmap, frameDelays, frameCount, frameSize); } if (!frameCount) return; HRGN rgn; if (options->avatarRadius) { rgn = CreateRoundRectRgn(x, y, x + w, y + h, 2 * options->avatarRadius, 2 * options->avatarRadius); SelectClipRgn(bmp->getDC(), rgn); } else { rgn = CreateRectRgn(x, y, x + w, y + h); } HDC hdcTmp = CreateCompatibleDC(bmp->getDC()); SelectObject(hdcTmp, hBitmap); SetStretchBltMode(bmp->getDC(), HALFTONE); if (av->dwFlags & AVS_PREMULTIPLIED) { BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 255; bf.AlphaFormat = AC_SRC_ALPHA; AlphaBlend(bmp->getDC(), x, y, w, h, hdcTmp, frameSize.cx*activeFrame, 0, frameSize.cx, frameSize.cy, bf); if (options->avatarBorders && options->avatarPNGBorders) { HBRUSH hbr = CreateSolidBrush(fonts.clAvatarBorder); bmp->saveAlpha(x, y, w, h); FrameRgn(bmp->getDC(), rgn, hbr, 1, 1); DeleteObject(hbr); bmp->restoreAlpha(x, y, w, h); } } else { bmp->saveAlpha(x, y, w, h); StretchBlt(bmp->getDC(), x, y, w, h, hdcTmp, frameSize.cx*activeFrame, 0, frameSize.cx, frameSize.cy, SRCCOPY); if (options->avatarBorders) { HBRUSH hbr = CreateSolidBrush(fonts.clAvatarBorder); FrameRgn(bmp->getDC(), rgn, hbr, 1, 1); DeleteObject(hbr); } bmp->restoreAlpha(x, y, w, h); } DeleteObject(rgn); SelectClipRgn(bmp->getDC(), NULL); DeleteDC(hdcTmp); activeFrame = (activeFrame + 1) % frameCount; }
static VOID MonSelMoveDragRect(IN OUT PMONITORSELWND infoPtr, IN PPOINT ppt) { RECT rcPrev, rcUpdate, *prc; HRGN hRgnPrev; HDC hDC; if (infoPtr->CanDisplay) { hDC = GetDC(infoPtr->hSelf); if (hDC != NULL) { if (infoPtr->ptDrag.x != ppt->x || infoPtr->ptDrag.y != ppt->y) { infoPtr->ptDrag = *ppt; rcPrev = infoPtr->rcDragging; /* Calculate updated dragging rectangle */ prc = &infoPtr->Monitors[infoPtr->DraggingMonitor].rc; infoPtr->rcDragging.left = ppt->x - infoPtr->DraggingMargin.cx; infoPtr->rcDragging.top = ppt->y - infoPtr->DraggingMargin.cy; infoPtr->rcDragging.right = infoPtr->rcDragging.left + (prc->right - prc->left); infoPtr->rcDragging.bottom = infoPtr->rcDragging.top + (prc->bottom - prc->top); hRgnPrev = CreateRectRgn(rcPrev.left, rcPrev.top, rcPrev.right, rcPrev.bottom); if (hRgnPrev != NULL) { if (!ScrollDC(hDC, infoPtr->rcDragging.left - rcPrev.left, infoPtr->rcDragging.top - rcPrev.top, &rcPrev, NULL, hRgnPrev, &rcUpdate) || !InvalidateRgn(infoPtr->hSelf, hRgnPrev, TRUE)) { DeleteObject(hRgnPrev); goto InvRects; } DeleteObject(hRgnPrev); } else { InvRects: InvalidateRect(infoPtr->hSelf, &rcPrev, TRUE); InvalidateRect(infoPtr->hSelf, &infoPtr->rcDragging, TRUE); } } ReleaseDC(infoPtr->hSelf, hDC); } } }
HRGN CSplashScreenEx::CreateRgnFromBitmap(HBITMAP hBmp, COLORREF color) { // this code is written by Davide Pizzolato if (!hBmp) return NULL; BITMAP bm; GetObject( hBmp, sizeof(BITMAP), &bm ); // get bitmap attributes CDC dcBmp; dcBmp.CreateCompatibleDC(GetDC()); //Creates a memory device context for the bitmap dcBmp.SelectObject(hBmp); //selects the bitmap in the device context const DWORD RDHDR = sizeof(RGNDATAHEADER); const DWORD MAXBUF = 40; // size of one block in RECTs // (i.e. MAXBUF*sizeof(RECT) in bytes) LPRECT pRects; DWORD cBlocks = 0; // number of allocated blocks INT i, j; // current position in mask image INT first = 0; // left position of current scan line // where mask was found bool wasfirst = false; // set when if mask was found in current scan line bool ismask; // set when current color is mask color // allocate memory for region data RGNDATAHEADER* pRgnData = (RGNDATAHEADER*)new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ]; memset( pRgnData, 0, RDHDR + cBlocks * MAXBUF * sizeof(RECT) ); // fill it by default pRgnData->dwSize = RDHDR; pRgnData->iType = RDH_RECTANGLES; pRgnData->nCount = 0; for ( i = 0; i < bm.bmHeight; i++ ) for ( j = 0; j < bm.bmWidth; j++ ){ // get color ismask=(dcBmp.GetPixel(j,bm.bmHeight-i-1)!=color); // place part of scan line as RECT region if transparent color found after mask color or // mask color found at the end of mask image if (wasfirst && ((ismask && (j==(bm.bmWidth-1)))||(ismask ^ (j<bm.bmWidth)))){ // get offset to RECT array if RGNDATA buffer pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR); // save current RECT pRects[ pRgnData->nCount++ ] = CRect( first, bm.bmHeight - i - 1, j+(j==(bm.bmWidth-1)), bm.bmHeight - i ); // if buffer full reallocate it if ( pRgnData->nCount >= cBlocks * MAXBUF ){ LPBYTE pRgnDataNew = new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ]; memcpy( pRgnDataNew, pRgnData, RDHDR + (cBlocks - 1) * MAXBUF * sizeof(RECT) ); delete pRgnData; pRgnData = (RGNDATAHEADER*)pRgnDataNew; } wasfirst = false; } else if ( !wasfirst && ismask ){ // set wasfirst when mask is found first = j; wasfirst = true; } } dcBmp.DeleteDC(); //release the bitmap // create region /* Under WinNT the ExtCreateRegion returns NULL (by [email protected]) */ // HRGN hRgn = ExtCreateRegion( NULL, RDHDR + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData ); /* ExtCreateRegion replacement { */ HRGN hRgn=CreateRectRgn(0, 0, 0, 0); ASSERT( hRgn!=NULL ); pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR); for(i=0;i<(int)pRgnData->nCount;i++) { HRGN hr=CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom); VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR)!=ERROR); if (hr) DeleteObject(hr); } ASSERT( hRgn!=NULL ); /* } ExtCreateRegion replacement */ delete pRgnData; return hRgn; }
BOOL CALLBACK VBoxEnumFunc(HWND hwnd, LPARAM lParam) { PVBOX_ENUM_PARAM lpParam = (PVBOX_ENUM_PARAM)lParam; DWORD dwStyle, dwExStyle; RECT rectWindow, rectVisible; dwStyle = GetWindowLong(hwnd, GWL_STYLE); dwExStyle = GetWindowLong(hwnd, GWL_EXSTYLE); if ( !(dwStyle & WS_VISIBLE) || (dwStyle & WS_CHILD)) return TRUE; Log(("VBoxTray: VBoxEnumFunc %x\n", hwnd)); /* Only visible windows that are present on the desktop are interesting here */ if (GetWindowRect(hwnd, &rectWindow)) { char szWindowText[256]; szWindowText[0] = 0; OSVERSIONINFO OSinfo; HWND hStart = NULL; GetWindowText(hwnd, szWindowText, sizeof(szWindowText)); OSinfo.dwOSVersionInfoSize = sizeof (OSinfo); GetVersionEx (&OSinfo); if (OSinfo.dwMajorVersion >= 6) { hStart = ::FindWindowEx(GetDesktopWindow(), NULL, "Button", "Start"); if ( hwnd == hStart && szWindowText != NULL && !(strcmp(szWindowText, "Start")) ) { /* for vista and above. To solve the issue of small bar above * the Start button when mouse is hovered over the start button in seamless mode. * Difference of 7 is observed in Win 7 platform between the dimensionsof rectangle with Start title and its shadow. */ rectWindow.top += 7; rectWindow.bottom -=7; } } rectVisible = rectWindow; #ifdef LOG_ENABLED DWORD pid = 0; DWORD tid = GetWindowThreadProcessId(hwnd, &pid); #endif /* Filter out Windows XP shadow windows */ /** @todo still shows inside the guest */ if ( szWindowText[0] == 0 && ( (dwStyle == (WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS) && dwExStyle == (WS_EX_LAYERED|WS_EX_TOOLWINDOW|WS_EX_TRANSPARENT|WS_EX_TOPMOST)) || (dwStyle == (WS_POPUP|WS_VISIBLE|WS_DISABLED|WS_CLIPSIBLINGS|WS_CLIPCHILDREN) && dwExStyle == (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_NOACTIVATE)) || (dwStyle == (WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN) && dwExStyle == (WS_EX_TOOLWINDOW)) )) { Log(("VBoxTray: Filter out shadow window style=%x exstyle=%x\n", dwStyle, dwExStyle)); Log(("VBoxTray: Enum hwnd=%x rect (%d,%d) (%d,%d) (filtered)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom)); Log(("VBoxTray: title=%s style=%x exStyle=%x\n", szWindowText, dwStyle, dwExStyle)); Log(("VBoxTray: pid=%d tid=%d\n", pid, tid)); return TRUE; } /** @todo will this suffice? The Program Manager window covers the whole screen */ if (strcmp(szWindowText, "Program Manager")) { Log(("VBoxTray: Enum hwnd=%x rect (%d,%d) (%d,%d) (applying)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom)); Log(("VBoxTray: title=%s style=%x exStyle=%x\n", szWindowText, dwStyle, dwExStyle)); Log(("VBoxTray: pid=%d tid=%d\n", pid, tid)); HRGN hrgn = CreateRectRgn(0,0,0,0); int ret = GetWindowRgn(hwnd, hrgn); if (ret == ERROR) { Log(("VBoxTray: GetWindowRgn failed with rc=%d\n", GetLastError())); SetRectRgn(hrgn, rectVisible.left, rectVisible.top, rectVisible.right, rectVisible.bottom); } else { /* this region is relative to the window origin instead of the desktop origin */ OffsetRgn(hrgn, rectWindow.left, rectWindow.top); } if (lpParam->hrgn) { /* create a union of the current visible region and the visible rectangle of this window. */ CombineRgn(lpParam->hrgn, lpParam->hrgn, hrgn, RGN_OR); DeleteObject(hrgn); } else lpParam->hrgn = hrgn; } else { Log(("VBoxTray: Enum hwnd=%x rect (%d,%d) (%d,%d) (ignored)\n", hwnd, rectWindow.left, rectWindow.top, rectWindow.right, rectWindow.bottom)); Log(("VBoxTray: title=%s style=%x\n", szWindowText, dwStyle)); Log(("VBoxTray: pid=%d tid=%d\n", pid, tid)); } } return TRUE; /* continue enumeration */ }
inline BOOL HookHandle(UINT MessageId, HWND hWnd, WPARAM wParam, LPARAM lParam) { //////////////////////////////////////////////////////////////// // HANDLE DEFERRED UPDATES // Is this a deferred-update message? if (MessageId == VNC_DEFERRED_UPDATE) { // NOTE : NEVER use the SendDeferred- routines to send updates // from here, or you'll get an infinite loop....! // NB : The format of DEFERRED_UPDATE matches that of UpdateRectMessage, // so just send the exact same message data to WinVNC PostThreadMessage( vnc_thread_id, UpdateRectMessage, wParam, lParam ); return FALSE; } // *** Could use WM_COPYDATA to send data to WinVNC /* if (GetClassLong(hWnd, GCW_ATOM) == 32768) { _RPT4(_CRT_WARN, "DBG : popup menu message (hwnd=%d, msg=%d, l=%d, w=%d)\n", hWnd, MessageId, lParam, wParam); } */ //////////////////////////////////////////////////////////////// // UPDATE-TRIGGERING MESSAGES // Do something dependent upon message type switch (MessageId) { //////////////////////////////////////////////////////////////// // Messages indicating only a border repaint. case WM_NCPAINT: case WM_NCACTIVATE: SendDeferredBorderRect(hWnd); old_cursor = NULL; break; //////////////////////////////////////////////////////////////// // Messages indicating a client area repaint case WM_CHAR: case WM_KEYUP: // Handle key-presses case WM_KEYDOWN: if (prf_use_KeyPress) SendDeferredWindowRect(hWnd); break; case WM_LBUTTONUP: // Handle LMB clicks if (prf_use_LButtonUp) SendDeferredWindowRect(hWnd); break; case WM_MBUTTONUP: // Handle MMB clicks if (prf_use_MButtonUp) SendDeferredWindowRect(hWnd); break; case WM_RBUTTONUP: // Handle RMB clicks if (prf_use_RButtonUp) SendDeferredWindowRect(hWnd); break; case WM_TIMER: if (prf_use_Timer) SendDeferredWindowRect(hWnd); break; case WM_HSCROLL: case WM_VSCROLL: if (((int) LOWORD(wParam) == SB_THUMBTRACK) || ((int) LOWORD(wParam) == SB_ENDSCROLL)) SendDeferredWindowRect(hWnd); break; case 485: // HACK to handle popup menus { // Get the old popup menu selection value HANDLE prop = GetProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0)); if (prop != (HANDLE) wParam) { // It did, so update the menu & the selection value SendDeferredWindowRect(hWnd); SetProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0), (HANDLE) wParam); } } break; //////////////////////////////////////////////////////////////// // Messages indicating a full window update case WM_SYSCOLORCHANGE: case WM_PALETTECHANGED: case WM_SETTEXT: case WM_ENABLE: case BM_SETCHECK: case BM_SETSTATE: case EM_SETSEL: //case WM_MENUSELECT: SendDeferredWindowRect(hWnd); break; //////////////////////////////////////////////////////////////// // Messages indicating that an area of the window needs updating // Uses GetUpdateRect to find out which case WM_PAINT: if (prf_use_GetUpdateRect) { HRGN region; region = CreateRectRgn(0, 0, 0, 0); // Get the affected region if (GetUpdateRgn(hWnd, region, FALSE) != ERROR) { int buffsize; UINT x; RGNDATA *buff; POINT TopLeft; // Get the top-left point of the client area TopLeft.x = 0; TopLeft.y = 0; if (!ClientToScreen(hWnd, &TopLeft)) break; // Get the size of buffer required buffsize = GetRegionData(region, 0, 0); if (buffsize != 0) { buff = (RGNDATA *) new BYTE [buffsize]; if (buff == NULL) break; // Now get the region data if(GetRegionData(region, buffsize, buff)) { for (x=0; x<(buff->rdh.nCount); x++) { // Obtain the rectangles from the list RECT *urect = (RECT *) (((BYTE *) buff) + sizeof(RGNDATAHEADER) + (x * sizeof(RECT))); SendDeferredUpdateRect( hWnd, (SHORT) (TopLeft.x + urect->left), (SHORT) (TopLeft.y + urect->top), (SHORT) (TopLeft.x + urect->right), (SHORT) (TopLeft.y + urect->bottom) ); // Modified by mws for VNC ver. 3.3.6 // We yield this thread so our PostMessages and socket commands // can complete, otherwise this hook can suck up too many // timeslices before it returns Sleep (0); } } delete [] buff; } } // Now free the region if (region != NULL) DeleteObject(region); } else SendDeferredWindowRect(hWnd); break; //////////////////////////////////////////////////////////////// // Messages indicating full repaint of this and a different window // Send the new position of the window case WM_WINDOWPOSCHANGING: if (IsWindowVisible(hWnd)) SendWindowRect(hWnd); break; case WM_WINDOWPOSCHANGED: if (IsWindowVisible(hWnd)) SendDeferredWindowRect(hWnd); break; //////////////////////////////////////////////////////////////// // WinVNC also wants to know about mouse movement case WM_NCMOUSEMOVE: case WM_MOUSEMOVE: // Inform WinVNC that the mouse has moved and pass it the current cursor handle { ULONG new_cursor = (ULONG)GetCursor(); if (new_cursor != old_cursor) { PostThreadMessage( vnc_thread_id, MouseMoveMessage, (ULONG) new_cursor, 0); old_cursor=new_cursor; } } break; // RealVNC 335 case WM_MOUSEWHEEL: // Handle mousewheel events SendDeferredWindowRect(hWnd); break; //////////////////////////////////////////////////////////////// // VNCHOOKS PROPERTIES HANDLING WINDOWS case WM_DESTROY: RemoveProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0)); break; } return TRUE; }
/*********************************************************************** * X11DRV_ExtTextOut */ BOOL X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR wstr, UINT count, const INT *lpDx ) { unsigned int i; fontObject* pfo; XFontStruct* font; BOOL rotated = FALSE; XChar2b *str2b = NULL; BOOL dibUpdateFlag = FALSE; BOOL result = TRUE; HRGN saved_region = 0; if(physDev->has_gdi_font) return X11DRV_XRender_ExtTextOut(physDev, x, y, flags, lprect, wstr, count, lpDx); if (!X11DRV_SetupGCForText( physDev )) return TRUE; pfo = XFONT_GetFontObject( physDev->font ); font = pfo->fs; if (pfo->lf.lfEscapement && pfo->lpX11Trans) rotated = TRUE; TRACE("hdc=%p df=%04x %d,%d %s, %d flags=%d lpDx=%p\n", physDev->hdc, (UINT16)(physDev->font), x, y, debugstr_wn (wstr, count), count, flags, lpDx); if (lprect != NULL) TRACE("\trect=(%d,%d - %d,%d)\n", lprect->left, lprect->top, lprect->right, lprect->bottom ); /* Draw the rectangle */ if (flags & ETO_OPAQUE) { X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod ); dibUpdateFlag = TRUE; wine_tsx11_lock(); XSetForeground( gdi_display, physDev->gc, physDev->backgroundPixel ); XFillRectangle( gdi_display, physDev->drawable, physDev->gc, physDev->dc_rect.left + lprect->left, physDev->dc_rect.top + lprect->top, lprect->right - lprect->left, lprect->bottom - lprect->top ); wine_tsx11_unlock(); } if (!count) goto END; /* Nothing more to do */ /* Set the clip region */ if (flags & ETO_CLIPPED) { HRGN clip_region; clip_region = CreateRectRgnIndirect( lprect ); /* make a copy of the current device region */ saved_region = CreateRectRgn( 0, 0, 0, 0 ); CombineRgn( saved_region, physDev->region, 0, RGN_COPY ); X11DRV_SetDeviceClipping( physDev, saved_region, clip_region ); DeleteObject( clip_region ); } /* Draw the text background if necessary */ if (!dibUpdateFlag) { X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod ); dibUpdateFlag = TRUE; } /* Draw the text (count > 0 verified) */ if (!(str2b = X11DRV_cptable[pfo->fi->cptable].punicode_to_char2b( pfo, wstr, count ))) goto FAIL; wine_tsx11_lock(); XSetForeground( gdi_display, physDev->gc, physDev->textPixel ); wine_tsx11_unlock(); if(!rotated) { if (!lpDx) { X11DRV_cptable[pfo->fi->cptable].pDrawString( pfo, gdi_display, physDev->drawable, physDev->gc, physDev->dc_rect.left + x, physDev->dc_rect.top + y, str2b, count ); } else { XTextItem16 *items, *pitem; pitem = items = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XTextItem16) ); if(items == NULL) goto FAIL; for(i = 0; i < count; i++) { pitem->chars = str2b + i; pitem->delta = lpDx[i]; pitem->nchars = 1; pitem->font = None; pitem++; } X11DRV_cptable[pfo->fi->cptable].pDrawText( pfo, gdi_display, physDev->drawable, physDev->gc, physDev->dc_rect.left + x, physDev->dc_rect.top + y, items, pitem - items ); HeapFree( GetProcessHeap(), 0, items ); } } else /* rotated */ { /* have to render character by character. */ double offset = 0.0; int i; for (i=0; i<count; i++) { int char_metric_offset = str2b[i].byte2 + (str2b[i].byte1 << 8) - font->min_char_or_byte2; int x_i = IROUND((double) (physDev->dc_rect.left + x) + offset * pfo->lpX11Trans->a / pfo->lpX11Trans->pixelsize ); int y_i = IROUND((double) (physDev->dc_rect.top + y) - offset * pfo->lpX11Trans->b / pfo->lpX11Trans->pixelsize ); X11DRV_cptable[pfo->fi->cptable].pDrawString( pfo, gdi_display, physDev->drawable, physDev->gc, x_i, y_i, &str2b[i], 1); if (lpDx) { offset += lpDx[i]; } else { offset += (double) (font->per_char ? font->per_char[char_metric_offset].attributes: font->min_bounds.attributes) * pfo->lpX11Trans->pixelsize / 1000.0; } } } HeapFree( GetProcessHeap(), 0, str2b ); if (flags & ETO_CLIPPED) { /* restore the device region */ X11DRV_SetDeviceClipping( physDev, saved_region, 0 ); DeleteObject( saved_region ); } goto END; FAIL: HeapFree( GetProcessHeap(), 0, str2b ); result = FALSE; END: if (dibUpdateFlag) X11DRV_UnlockDIBSection( physDev, TRUE ); return result; }
// static HRGN Path::SubtractRegion(HRGN r1, HRGN r2) { HRGN dest = CreateRectRgn(0, 0, 1, 1); CombineRgn(dest, r1, r2, RGN_DIFF); return dest; }
/** * @brief Draw a line. * @note Optional - The high level driver can emulate using software. * * @param[in] x0, y0 The start of the line * @param[in] x1, y1 The end of the line * @param[in] color The color of the line * * @notapi */ void GDISP_LLD(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) { POINT p; HPEN pen; HDC dc; HGDIOBJ old; #if GDISP_NEED_CLIP HRGN clip; #endif #if WIN32_USE_MSG_REDRAW RECT rect; #endif #if GDISP_NEED_CONTROL coord_t t; #endif #if GDISP_NEED_CLIP clip = NULL; #endif #if GDISP_NEED_CONTROL switch(GDISP.Orientation) { case GDISP_ROTATE_0: #if GDISP_NEED_CLIP // Clip post orientation change if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height) clip = CreateRectRgn(GDISP.clipx0, GDISP.clipy0, GDISP.clipx1, GDISP.clipy1); #endif break; case GDISP_ROTATE_90: t = GDISP.Height - 1 - y0; y0 = x0; x0 = t; t = GDISP.Height - 1 - y1; y1 = x1; x1 = t; #if GDISP_NEED_CLIP // Clip post orientation change if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height) clip = CreateRectRgn(GDISP.Height-1-GDISP.clipy1, GDISP.clipx0, GDISP.Height-1-GDISP.clipy0, GDISP.clipx1); #endif break; case GDISP_ROTATE_180: x0 = GDISP.Width - 1 - x0; y0 = GDISP.Height - 1 - y0; x1 = GDISP.Width - 1 - x1; y1 = GDISP.Height - 1 - y1; #if GDISP_NEED_CLIP // Clip post orientation change if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height) clip = CreateRectRgn(GDISP.Width-1-GDISP.clipx1, GDISP.Height-1-GDISP.clipy1, GDISP.Width-1-GDISP.clipx0, GDISP.Height-1-GDISP.clipy0); #endif break; case GDISP_ROTATE_270: t = GDISP.Width - 1 - x0; x0 = y0; y0 = t; t = GDISP.Width - 1 - x1; x1 = y1; y1 = t; #if GDISP_NEED_CLIP // Clip post orientation change if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height) clip = CreateRectRgn(GDISP.clipy0, GDISP.Width-1-GDISP.clipx1, GDISP.clipy1, GDISP.Width-1-GDISP.clipx0); #endif break; } #else #if GDISP_NEED_CLIP clip = NULL; if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height) clip = CreateRectRgn(GDISP.clipx0, GDISP.clipy0, GDISP.clipx1, GDISP.clipy1); #endif #endif color = COLOR2BGR(color); pen = CreatePen(PS_SOLID, 1, color); if (pen) { // Draw the line in the buffer #if GDISP_NEED_CLIP if (clip) SelectClipRgn(dcBuffer, clip); #endif old = SelectObject(dcBuffer, pen); MoveToEx(dcBuffer, x0, y0, &p); LineTo(dcBuffer, x1, y1); SelectObject(dcBuffer, old); SetPixel(dcBuffer, x1, y1, color); #if GDISP_NEED_CLIP if (clip) SelectClipRgn(dcBuffer, NULL); #endif #if WIN32_USE_MSG_REDRAW rect.left = x0; rect.right = x1+1; rect.top = y0; rect.bottom = y1+1; InvalidateRect(winRootWindow, &rect, FALSE); UpdateWindow(winRootWindow); #else // Redrawing the line on the screen is cheaper than invalidating the whole rectangular area dc = GetDC(winRootWindow); #if GDISP_NEED_CLIP if (clip) SelectClipRgn(dc, clip); #endif old = SelectObject(dc, pen); MoveToEx(dc, x0, y0, &p); LineTo(dc, x1, y1); SelectObject(dc, old); SetPixel(dc, x1, y1, color); #if GDISP_NEED_CLIP if (clip) SelectClipRgn(dc, NULL); #endif ReleaseDC(winRootWindow, dc); #endif DeleteObject(pen); } }
int GetWindowVisibleState(HWND hWnd, int iStepX, int iStepY) { RECT rc = { 0 }; POINT pt = { 0 }; HRGN rgn=NULL; register int i = 0, j = 0, width = 0, height = 0, iCountedDots = 0, iNotCoveredDots = 0; BOOL bPartiallyCovered = FALSE; HWND hAux = 0; int res=0; if (hWnd == NULL) { SetLastError(0x00000006); //Wrong handle return -1; } //Some defaults now. The routine is designed for thin and tall windows. if (iStepX <= 0) iStepX = 8; if (iStepY <= 0) iStepY = 16; if (IsIconic(hWnd) || !IsWindowVisible(hWnd)) return GWVS_HIDDEN; else { int hstep,vstep; BITMAP bmp; HBITMAP WindowImage; int maxx=0; int maxy=0; int wx=0; int dx,dy; BYTE *ptr=NULL; HRGN rgn=NULL; WindowImage=LayeredFlag?GetCurrentWindowImage():0; if (WindowImage&&LayeredFlag) { GetObject(WindowImage,sizeof(BITMAP),&bmp); ptr=bmp.bmBits; maxx=bmp.bmWidth; maxy=bmp.bmHeight; wx=bmp.bmWidthBytes; } else { RECT rc; int i=0; rgn=CreateRectRgn(0,0,1,1); GetWindowRect(hWnd,&rc); GetWindowRgn(hWnd,rgn); OffsetRgn(rgn,rc.left,rc.top); GetRgnBox(rgn,&rc); i=i; //maxx=rc.right; //maxy=rc.bottom; } GetWindowRect(hWnd, &rc); { RECT rcMonitor={0}; Docking_GetMonitorRectFromWindow(hWnd,&rcMonitor); rc.top=rc.top<rcMonitor.top?rcMonitor.top:rc.top; rc.left=rc.left<rcMonitor.left?rcMonitor.left:rc.left; rc.bottom=rc.bottom>rcMonitor.bottom?rcMonitor.bottom:rc.bottom; rc.right=rc.right>rcMonitor.right?rcMonitor.right:rc.right; } width = rc.right - rc.left; height = rc.bottom- rc.top; dx=-rc.left; dy=-rc.top; hstep=width/iStepX; vstep=height/iStepY; hstep=hstep>0?hstep:1; vstep=vstep>0?vstep:1; for (i = rc.top; i < rc.bottom; i+=vstep) { pt.y = i; for (j = rc.left; j < rc.right; j+=hstep) { BOOL po=FALSE; pt.x = j; if (rgn) po=PtInRegion(rgn,j,i); else po=(GetDIBPixelColor(j+dx,i+dy,maxx,maxy,wx,ptr)&0xFF000000)!=0; if (po||(!rgn&&ptr==0)) { BOOL hWndFound=FALSE; HWND hAuxOld=NULL; hAux = WindowFromPoint(pt); do { if (hAux==hWnd) { hWndFound=TRUE; break; } //hAux = GetParent(hAux); hAuxOld=hAux; hAux = GetAncestor(hAux,GA_ROOTOWNER); if (hAuxOld==hAux) { TCHAR buf[255]; GetClassName(hAux,buf,SIZEOF(buf)); if (!lstrcmp(buf,_T(CLUIFrameSubContainerClassName))) { hWndFound=TRUE; break; } } }while(hAux!= NULL &&hAuxOld!=hAux); if (hWndFound) //There's window! iNotCoveredDots++; //Let's count the not covered dots. //{ // //bPartiallyCovered = TRUE; // //iCountedDots++; // //break; //} //else iCountedDots++; //Let's keep track of how many dots we checked. } } } if (rgn) DeleteObject(rgn); if (iNotCoveredDots == iCountedDots) //Every dot was not covered: the window is visible. return GWVS_VISIBLE; else if (iNotCoveredDots == 0) //They're all covered! return GWVS_COVERED; else //There are dots which are visible, but they are not as many as the ones we counted: it's partially covered. return GWVS_PARTIALLY_COVERED; } }
int CALLBACK ButtonX::windowProc(HWND hwnd , int message , WPARAM wParam, LPARAM lParam) { switch(message) { case WM_SETTEXT: ButtonX::fromHWND(hwnd)->_text = (char*) lParam; //break; return 0; case WM_GETTEXT: if (ButtonX::fromHWND(hwnd)->_duringPaint) { ((char*)lParam)[0] = 0; return 0; } //break; // strncpy((char*) lParam,ButtonX::fromHWND(hwnd)->_text , wParam); strncpy((char*) lParam,ButtonX::fromHWND(hwnd)->_text , wParam); return min(ButtonX::fromHWND(hwnd)->_text.length(), wParam-1); case WM_GETTEXTLENGTH: if (ButtonX::fromHWND(hwnd)->_duringPaint) return 0; //break; return ButtonX::fromHWND(hwnd)->_text.length(); case WM_PAINT: { ButtonX * bt = ButtonX::fromHWND(hwnd); //if (!bt->_icon) break; // standardowa obs³uga... //int r = 1; HRGN hrgn=CreateRectRgn(0, 0, 0, 0); bt->_duringPaint=true; GetUpdateRgn(hwnd, hrgn, false); int r = 1; if (!bt->isFlat()) { r = CallWindowProc(ButtonX::buttonClassProc, hwnd, message, wParam, lParam); } InvalidateRgn(hwnd, hrgn, false); PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint(hwnd, &ps); if (bt->isFlat()) { FillRgn(hdc, hrgn, GetSysColorBrush(COLOR_BTNFACE)); } RECT rc = {0,0,0,0}; bt->drawCaption(hdc, rc); EndPaint(hwnd, &ps); bt->_duringPaint=false; DeleteObject(hrgn); return r;} case WM_ENABLE: case WM_UPDATEUISTATE: { int r = CallWindowProc(ButtonX::buttonClassProc, hwnd, message, wParam, lParam); repaintWindow(hwnd); return r;} case WM_ERASEBKGND: return 0; case WM_SETFOCUS: //case BM_SETSTYLE: case BM_SETSTATE: // specjalnie dla W98 repaintWindow(hwnd); break; case WM_SETCURSOR: if (fromHWND(hwnd)->isFlat()) { SetCursor( LoadCursor(0, IDC_HAND) ); return true; } break; #ifndef STAMINA_KISS case WM_LBUTTONDOWN: { ButtonX* b = fromHWND(hwnd); S_ASSERT(b); b->_pressed = true; b->evtMouseDown(b, wParam); break;} case WM_LBUTTONUP: { ButtonX* b = fromHWND(hwnd); S_ASSERT(b); if (b->_pressed) { b->evtMouseUp(b, wParam); if (getClientRect(hwnd).contains(Point::fromLParam(lParam))) { b->evtClick(b); } } b->_pressed = false; break;} case WM_LBUTTONDBLCLK: { //SendMessage(hwnd, BM_CLICK, 0, 0); ButtonX* b = fromHWND(hwnd); S_ASSERT(b); b->evtMouseDown(b, wParam); b->evtMouseUp(b, wParam); b->evtClick(b); break;} case WM_MOUSELEAVE: //fromHWND(hwnd)->_pressed = false; break; case WM_MOUSEMOVE: _tipTarget->attachButton(fromHWND(hwnd)); ToolTipX::mouseMovement(GetParent(hwnd)); //if (wParam == MK_LBUTTON) { // fromHWND(hwnd)->_pressed = true; //} break; #endif case WM_DESTROY: delete ButtonX::fromHWND(hwnd); break; }; return CallWindowProc(ButtonX::buttonClassProc, hwnd, message, wParam, lParam); }
/****************************************************************************** * SetBitmapBits [GDI32.@] * * Sets bits of color data for a bitmap. * * RETURNS * Success: Number of bytes used in setting the bitmap bits * Failure: 0 */ LONG WINAPI SetBitmapBits( HBITMAP hbitmap, /* [in] Handle to bitmap */ LONG count, /* [in] Number of bytes in bitmap array */ LPCVOID bits) /* [in] Address of array with bitmap bits */ { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; BITMAPOBJ *bmp; DWORD err; int i, src_stride, dst_stride; struct bitblt_coords src, dst; struct gdi_image_bits src_bits; HRGN clip = NULL; const struct gdi_dc_funcs *funcs; if (!bits) return 0; bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ); if (!bmp) return 0; funcs = get_bitmap_funcs( bmp ); if (count < 0) { WARN("(%d): Negative number of bytes passed???\n", count ); count = -count; } if (bmp->dib) src_stride = get_bitmap_stride( bmp->dib->dsBmih.biWidth, bmp->dib->dsBmih.biBitCount ); else src_stride = get_bitmap_stride( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel ); count = min( count, src_stride * bmp->bitmap.bmHeight ); dst_stride = get_dib_stride( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel ); src.visrect.left = src.x = 0; src.visrect.top = src.y = 0; src.visrect.right = src.width = bmp->bitmap.bmWidth; src.visrect.bottom = src.height = (count + src_stride - 1 ) / src_stride; dst = src; if (count % src_stride) { HRGN last_row; int extra_pixels = ((count % src_stride) << 3) / bmp->bitmap.bmBitsPixel; if ((count % src_stride << 3) % bmp->bitmap.bmBitsPixel) FIXME( "Unhandled partial pixel\n" ); clip = CreateRectRgn( src.visrect.left, src.visrect.top, src.visrect.right, src.visrect.bottom - 1 ); last_row = CreateRectRgn( src.visrect.left, src.visrect.bottom - 1, src.visrect.left + extra_pixels, src.visrect.bottom ); CombineRgn( clip, clip, last_row, RGN_OR ); DeleteObject( last_row ); } TRACE("(%p, %d, %p) %dx%d %d bpp fetched height: %d\n", hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, bmp->bitmap.bmBitsPixel, src.height ); if (src_stride == dst_stride) { src_bits.ptr = (void *)bits; src_bits.is_copy = FALSE; src_bits.free = NULL; } else { if (!(src_bits.ptr = HeapAlloc( GetProcessHeap(), 0, dst.height * dst_stride ))) { GDI_ReleaseObj( hbitmap ); return 0; } src_bits.is_copy = TRUE; src_bits.free = free_heap_bits; for (i = 0; i < count / src_stride; i++) memcpy( (char *)src_bits.ptr + i * dst_stride, (char *)bits + i * src_stride, src_stride ); if (count % src_stride) memcpy( (char *)src_bits.ptr + i * dst_stride, (char *)bits + i * src_stride, count % src_stride ); } /* query the color info */ info->bmiHeader.biSize = sizeof(info->bmiHeader); info->bmiHeader.biPlanes = 1; info->bmiHeader.biBitCount = bmp->dib ? bmp->dib->dsBmih.biBitCount : bmp->bitmap.bmBitsPixel; info->bmiHeader.biCompression = BI_RGB; info->bmiHeader.biXPelsPerMeter = 0; info->bmiHeader.biYPelsPerMeter = 0; info->bmiHeader.biClrUsed = 0; info->bmiHeader.biClrImportant = 0; info->bmiHeader.biWidth = 0; info->bmiHeader.biHeight = 0; info->bmiHeader.biSizeImage = 0; err = funcs->pPutImage( NULL, hbitmap, 0, info, NULL, NULL, NULL, SRCCOPY ); if (!err || err == ERROR_BAD_FORMAT) { info->bmiHeader.biWidth = bmp->bitmap.bmWidth; info->bmiHeader.biHeight = -dst.height; info->bmiHeader.biSizeImage = dst.height * dst_stride; err = funcs->pPutImage( NULL, hbitmap, clip, info, &src_bits, &src, &dst, SRCCOPY ); } if (err) count = 0; if (clip) DeleteObject( clip ); if (src_bits.free) src_bits.free( &src_bits ); GDI_ReleaseObj( hbitmap ); return count; }
INT_PTR CALLBACK DlgProcAlarm(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { WindowData *wd = (WindowData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); Utils_RestoreWindowPositionNoSize(hwndDlg, 0, MODULENAME, "Notify"); SetFocus(GetDlgItem(hwndDlg, IDC_SNOOZE)); wd = new WindowData; wd->moving = false; wd->alarm = nullptr; wd->win_num = win_num++; if (wd->win_num > 0) { RECT r; GetWindowRect(hwndDlg, &r); r.top += 20; r.left += 20; SetWindowPos(hwndDlg, nullptr, r.left, r.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); Utils_SaveWindowPosition(hwndDlg, 0, MODULENAME, "Notify"); } SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)wd); // options SendMessage(hwndDlg, WMU_SETOPT, 0, 0); // fonts SendMessage(hwndDlg, WMU_SETFONTS, 0, 0); return FALSE; case WMU_REFRESH: InvalidateRect(hwndDlg, nullptr, TRUE); return TRUE; case WM_CTLCOLORSTATIC: { HDC hdc = (HDC)wParam; HWND hwndCtrl = (HWND)lParam; if (hBackgroundBrush) { if (hTitleFont && GetDlgItem(hwndDlg, IDC_TITLE) == hwndCtrl) SetTextColor(hdc, title_font_colour); else if (hWindowFont) SetTextColor(hdc, window_font_colour); SetBkMode(hdc, TRANSPARENT); return (INT_PTR)hBackgroundBrush; } } break; case WM_CTLCOLORDLG: if (hBackgroundBrush) return (INT_PTR)hBackgroundBrush; break; case WMU_SETFONTS: // fonts if (hWindowFont) SendMessage(hwndDlg, WM_SETFONT, (WPARAM)hWindowFont, TRUE); if (hTitleFont) SendDlgItemMessage(hwndDlg, IDC_TITLE, WM_SETFONT, (WPARAM)hTitleFont, TRUE); if (hBackgroundBrush) { SetClassLongPtr(hwndDlg, GCLP_HBRBACKGROUND, (LONG_PTR)hBackgroundBrush); InvalidateRect(hwndDlg, nullptr, TRUE); } return TRUE; case WMU_SETOPT: Options *opt; if (lParam) opt = (Options*)lParam; else opt = &options; // round corners if (opt->aw_roundcorners) { HRGN hRgn1; RECT r; int w = 10; GetWindowRect(hwndDlg, &r); int h = (r.right - r.left) > (w * 2) ? w : (r.right - r.left); int v = (r.bottom - r.top) > (w * 2) ? w : (r.bottom - r.top); h = (h < v) ? h : v; hRgn1 = CreateRoundRectRgn(0, 0, (r.right - r.left + 1), (r.bottom - r.top + 1), h, h); SetWindowRgn(hwndDlg, hRgn1, 1); } else { HRGN hRgn1; RECT r; int w = 10; GetWindowRect(hwndDlg, &r); int h = (r.right - r.left) > (w * 2) ? w : (r.right - r.left); int v = (r.bottom - r.top) > (w * 2) ? w : (r.bottom - r.top); h = (h < v) ? h : v; hRgn1 = CreateRectRgn(0, 0, (r.right - r.left + 1), (r.bottom - r.top + 1)); SetWindowRgn(hwndDlg, hRgn1, 1); } // transparency #ifdef WS_EX_LAYERED SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) | WS_EX_LAYERED); #endif #ifdef LWA_ALPHA SetLayeredWindowAttributes(hwndDlg, RGB(0, 0, 0), (int)((100 - opt->aw_trans) / 100.0 * 255), LWA_ALPHA); #endif return TRUE; case WMU_SETALARM: { ALARM *data = (ALARM *)lParam; SetWindowText(hwndDlg, data->szTitle); SetWindowText(GetDlgItem(hwndDlg, IDC_TITLE), data->szTitle); SetDlgItemText(hwndDlg, IDC_ED_DESC, data->szDesc); wd->alarm = data; if (data->action & AAF_SOUND && options.loop_sound) { if (data->sound_num <= 3) SetTimer(hwndDlg, ID_TIMER_SOUND, SOUND_REPEAT_PERIOD, nullptr); else if (data->sound_num == 4) SetTimer(hwndDlg, ID_TIMER_SOUND, SPEACH_REPEAT_PERIOD, nullptr); } HWND hw = GetDlgItem(hwndDlg, IDC_SNOOZE); EnableWindow(hw, !(data->flags & ALF_NOSNOOZE)); ShowWindow(hw, (data->flags & ALF_NOSNOOZE) ? SW_HIDE : SW_SHOWNA); } return TRUE; case WMU_FAKEALARM: SetWindowText(hwndDlg, TranslateT("Example alarm")); SetDlgItemText(hwndDlg, IDC_TITLE, TranslateT("Example alarm")); SetDlgItemText(hwndDlg, IDC_ED_DESC, TranslateT("Some example text. Example, example, example.")); return TRUE; case WM_TIMER: if (wParam == ID_TIMER_SOUND && wd) { ALARM *data = wd->alarm; if (data && data->action & AAF_SOUND) { if (data->sound_num <= 3) { char buff[128]; mir_snprintf(buff, "Triggered%d", data->sound_num); Skin_PlaySound(buff); } else if (data->sound_num == 4) { if (data->szTitle != nullptr && data->szTitle[0] != '\0') { if (ServiceExists("Speak/Say")) { CallService("Speak/Say", 0, (LPARAM)data->szTitle); } } } } } return TRUE; case WM_MOVE: Utils_SaveWindowPosition(hwndDlg, 0, MODULENAME, "Notify"); break; case WMU_ADDSNOOZER: if (wd) { ALARM *data = wd->alarm; if (data) { // add snooze minutes to current time FILETIME ft; GetLocalTime(&data->time); SystemTimeToFileTime(&data->time, &ft); ULARGE_INTEGER uli; uli.LowPart = ft.dwLowDateTime; uli.HighPart = ft.dwHighDateTime; // there are 10000000 100-nanosecond blocks in a second... uli.QuadPart += mult.QuadPart * (int)(wParam); ft.dwHighDateTime = uli.HighPart; ft.dwLowDateTime = uli.LowPart; FileTimeToSystemTime(&ft, &data->time); data->occurrence = OC_ONCE; data->snoozer = true; data->flags = data->flags & ~ALF_NOSTARTUP; data->id = next_alarm_id++; append_to_list(data); } } return TRUE; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case IDCANCEL: // no button - esc pressed case IDOK: // space? case IDC_SNOOZE: SendMessage(hwndDlg, WMU_ADDSNOOZER, (WPARAM)options.snooze_minutes, 0); //drop through case IDC_DISMISS: KillTimer(hwndDlg, ID_TIMER_SOUND); if (wd) { if (wd->alarm) { free_alarm_data(wd->alarm); delete wd->alarm; } delete wd; } SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); win_num--; WindowList_Remove(hAlarmWindowList, hwndDlg); DestroyWindow(hwndDlg); break; case IDC_SNOOZELIST: POINT pt, pt_rel; GetCursorPos(&pt); pt_rel = pt; ScreenToClient(hwndDlg, &pt_rel); HMENU hMenu = CreatePopupMenu(); MENUITEMINFO mii = { 0 }; mii.cbSize = sizeof(mii); mii.fMask = MIIM_ID | MIIM_STRING; #define AddItem(x) \ mii.wID++; \ mii.dwTypeData = TranslateW(x); \ mii.cch = ( UINT )mir_wstrlen(mii.dwTypeData); \ InsertMenuItem(hMenu, mii.wID, FALSE, &mii); AddItem(LPGENW("5 mins")); AddItem(LPGENW("15 mins")); AddItem(LPGENW("30 mins")); AddItem(LPGENW("1 hour")); AddItem(LPGENW("1 day")); AddItem(LPGENW("1 week")); TPMPARAMS tpmp = { 0 }; tpmp.cbSize = sizeof(tpmp); LRESULT ret = (LRESULT)TrackPopupMenuEx(hMenu, TPM_RETURNCMD, pt.x, pt.y, hwndDlg, &tpmp); switch (ret) { case 0: DestroyMenu(hMenu); return 0; // dismis menu case 1: SendMessage(hwndDlg, WMU_ADDSNOOZER, (WPARAM)5, 0); break; case 2: SendMessage(hwndDlg, WMU_ADDSNOOZER, (WPARAM)15, 0); break; case 3: SendMessage(hwndDlg, WMU_ADDSNOOZER, (WPARAM)30, 0); break; case 4: SendMessage(hwndDlg, WMU_ADDSNOOZER, (WPARAM)60, 0); break; case 5: SendMessage(hwndDlg, WMU_ADDSNOOZER, (WPARAM)(60 * 24), 0); break; case 6: SendMessage(hwndDlg, WMU_ADDSNOOZER, (WPARAM)(60 * 24 * 7), 0); break; } DestroyMenu(hMenu); SendMessage(hwndDlg, WM_COMMAND, IDC_DISMISS, 0); break; } } return TRUE; case WM_MOUSEMOVE: if (wParam & MK_LBUTTON) { SetCapture(hwndDlg); POINT newp; newp.x = (short)LOWORD(lParam); newp.y = (short)HIWORD(lParam); ClientToScreen(hwndDlg, &newp); if (!wd->moving) wd->moving = true; else { RECT r; GetWindowRect(hwndDlg, &r); SetWindowPos(hwndDlg, nullptr, r.left + (newp.x - wd->p.x), r.top + (newp.y - wd->p.y), 0, 0, SWP_NOSIZE | SWP_NOZORDER); } wd->p.x = newp.x; wd->p.y = newp.y; } else { ReleaseCapture(); wd->moving = false; } return TRUE; } return FALSE; }
/********************************************************************** * ExtEscape (X11DRV.@) */ INT X11DRV_ExtEscape( X11DRV_PDEVICE *physDev, INT escape, INT in_count, LPCVOID in_data, INT out_count, LPVOID out_data ) { switch(escape) { case QUERYESCSUPPORT: if (in_data) { switch (*(const INT *)in_data) { case DCICOMMAND: return DD_HAL_VERSION; case X11DRV_ESCAPE: return TRUE; } } break; case DCICOMMAND: if (in_data) { const DCICMD *lpCmd = in_data; if (lpCmd->dwVersion != DD_VERSION) break; return X11DRV_DCICommand(in_count, lpCmd, out_data); } break; case X11DRV_ESCAPE: if (in_data && in_count >= sizeof(enum x11drv_escape_codes)) { switch(*(const enum x11drv_escape_codes *)in_data) { case X11DRV_GET_DISPLAY: if (out_count >= sizeof(Display *)) { *(Display **)out_data = gdi_display; return TRUE; } break; case X11DRV_GET_DRAWABLE: if (out_count >= sizeof(Drawable)) { *(Drawable *)out_data = physDev->drawable; return TRUE; } break; case X11DRV_GET_FONT: if (out_count >= sizeof(Font)) { fontObject* pfo = XFONT_GetFontObject( physDev->font ); if (pfo == NULL) return FALSE; *(Font *)out_data = pfo->fs->fid; return TRUE; } break; case X11DRV_SET_DRAWABLE: if (in_count >= sizeof(struct x11drv_escape_set_drawable)) { const struct x11drv_escape_set_drawable *data = (const struct x11drv_escape_set_drawable *)in_data; if(physDev->xrender) X11DRV_XRender_UpdateDrawable( physDev ); physDev->dc_rect = data->dc_rect; physDev->drawable = data->drawable; physDev->drawable_rect = data->drawable_rect; physDev->current_pf = pixelformat_from_fbconfig_id( data->fbconfig_id ); physDev->gl_drawable = data->gl_drawable; physDev->pixmap = data->pixmap; physDev->gl_copy = data->gl_copy; wine_tsx11_lock(); XSetSubwindowMode( gdi_display, physDev->gc, data->mode ); wine_tsx11_unlock(); TRACE( "SET_DRAWABLE hdc %p drawable %lx gl_drawable %lx pf %u dc_rect %s drawable_rect %s\n", physDev->hdc, physDev->drawable, physDev->gl_drawable, physDev->current_pf, wine_dbgstr_rect(&physDev->dc_rect), wine_dbgstr_rect(&physDev->drawable_rect) ); return TRUE; } break; case X11DRV_START_EXPOSURES: wine_tsx11_lock(); XSetGraphicsExposures( gdi_display, physDev->gc, True ); wine_tsx11_unlock(); physDev->exposures = 0; return TRUE; case X11DRV_END_EXPOSURES: if (out_count >= sizeof(HRGN)) { HRGN hrgn = 0, tmp = 0; wine_tsx11_lock(); XSetGraphicsExposures( gdi_display, physDev->gc, False ); wine_tsx11_unlock(); if (physDev->exposures) { for (;;) { XEvent event; wine_tsx11_lock(); XWindowEvent( gdi_display, physDev->drawable, ~0, &event ); wine_tsx11_unlock(); if (event.type == NoExpose) break; if (event.type == GraphicsExpose) { int x = event.xgraphicsexpose.x - physDev->dc_rect.left; int y = event.xgraphicsexpose.y - physDev->dc_rect.top; TRACE( "got %d,%d %dx%d count %d\n", x, y, event.xgraphicsexpose.width, event.xgraphicsexpose.height, event.xgraphicsexpose.count ); if (!tmp) tmp = CreateRectRgn( 0, 0, 0, 0 ); SetRectRgn( tmp, x, y, x + event.xgraphicsexpose.width, y + event.xgraphicsexpose.height ); if (hrgn) CombineRgn( hrgn, hrgn, tmp, RGN_OR ); else { hrgn = tmp; tmp = 0; } if (!event.xgraphicsexpose.count) break; } else { ERR( "got unexpected event %d\n", event.type ); break; } } if (tmp) DeleteObject( tmp ); } *(HRGN *)out_data = hrgn; return TRUE; } break; case X11DRV_GET_DCE: case X11DRV_SET_DCE: FIXME( "%x escape no longer supported\n", *(const enum x11drv_escape_codes *)in_data ); break; case X11DRV_GET_GLX_DRAWABLE: if (out_count >= sizeof(Drawable)) { *(Drawable *)out_data = get_glxdrawable(physDev); return TRUE; } break; case X11DRV_SYNC_PIXMAP: if(physDev->bitmap) { X11DRV_CoerceDIBSection(physDev, DIB_Status_GdiMod); return TRUE; } return FALSE; case X11DRV_FLUSH_GL_DRAWABLE: flush_gl_drawable(physDev); return TRUE; } } break; } return 0; }
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); todo_wine { 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); }
//рисуем картину приложения void LinePicture(HWND hwnd, int Context) { //выбираем нужный контектс устройства для экрана //--------------------------------------------- HDC hdcWin; PAINTSTRUCT ps; //получаем контест устройства для экрана if(Context == 1) hdcWin = BeginPaint(hwnd, &ps); else hdcWin = GetDC(hwnd); //----------------------------------------------- //связываем размеры поля вывода с размерами клиентской области окна //-------------------------------------------------------------------- RECT rct; GetClientRect(hwnd,&rct); ne1 = rct.left+50; ne2 = rct.right -50; me1 = rct.bottom -50; me2 = rct.top + 50; //------------------------------------------------------------------ //создаем контекст экрана //------------------------------------------------------------ HDC hdc = CreateCompatibleDC(hdcWin); //создаем контекст //памяти связаный с контекстом экрана //памяти надо придать вид экрана - подходт битовая карта с форматом // как у экрана. В памяти будем рисовать на битовой карте HBITMAP hBitmap, hBitmapOld; hBitmap = CreateCompatibleBitmap(hdcWin, ne2, me1); //создаем //битовую карту совместмую с контекстом экрана hBitmapOld = (HBITMAP)SelectObject(hdc, hBitmap); //помещаем // битовую карту в контекст памяти //-------------------------------------------------------------- //выводи значения углов в верхней части поля вывода //-------------------------------------------------------- //создание прямоугольной области для вывода углов поворота HRGN hrgn2 = CreateRectRgn(ne1,me2-30,ne2,me1); //заливаем выделенную область серым цветом HBRUSH hBrush2 = CreateSolidBrush(RGB(0x80,0x80,0x80)); HBRUSH hBrushOld = (HBRUSH)SelectObject(hdc,hBrush2); FillRgn(hdc,hrgn2,hBrush2); SelectObject(hdc,hBrushOld); DeleteObject(hBrush2); DeleteObject(hrgn2); //вычисление угловых коэффициентов поворота системы координат sf=sin(M_PI*angl.fi/180); cf=cos(M_PI*angl.fi/180); st=sin(M_PI*angl.teta/180); ct=cos(M_PI*angl.teta/180); //информация об углах поворота системы координат TCHAR ss[20]; SetBkColor(hdc,RGB(0xC0,0xC0,0xC0)); SetTextColor(hdc,RGB(0,0,0x80)); swprintf_s(ss,20,L"fi = %4.0lf",angl.fi); TextOut(hdc,(ne1+ne2)/2-80,me2-25,ss,9); swprintf_s(ss,20,L"teta = %4.0lf",angl.teta); TextOut(hdc,(ne1+ne2)/2+20,me2-25,ss,11); //------------------------------------------------ //выделение памяти под Z-буфер и начальное его заполнение //------------------------------------------------------------- //вычисляем число пикселей в поле вывода Np = ne2-ne1 + 1, Mp = me1-me2 +1, NM = Np*Mp; //выделяем память под Z-буфер для каждого пикселя zb = new ZbuffS [NM]; //начальное заполнение z-буфера для каждого пикселя for ( long unsigned p=0; p<NM; p++) { zb[p].z = -1000; zb[p].c.R = 0xC0; zb[p].c.G = 0xC0; zb[p].c.B = 0xC0; } //----------------------------------------------------------- //"рисуем" магнитную пластинку заданным цветом заполняя Z-буфер //----------------------------------------------------------------------- //мировые координаты проецируемой точки double xt1,yt1,zt1; //видовые координаты проецируемой точки double xe,ye,ze1; //пиксельные координаты проецируемой точки int x1,y1; //пиксельные координаты 4-х углов пластинки int xp[4], yp[4]; //видовые z-координаты 4-х углов пластинки double ze[4]; for(int n=0; n<4; n++) { xt1 = Px[n]; yt1 = Py[n]; zt1 = Pz[n]; xe = Xe(xt1, yt1, zt1); ye=Ye(xt1,yt1,zt1); ze1=Ze(xt1,yt1,zt1); x1=xn(xe); y1=ym(ye); xp[n] = x1; yp[n] = y1; ze[n] = ze1; } //ZbufParallelogram(hdc,xp[0],yp[0],ze[0],xp[1],yp[1],ze[1], //xp[2],yp[2],ze[2],xp[3],yp[3],ze[3],RGB(255,255,0)); //------------------------------------------------------------------ //"рисуем" линии поля заполняя Z-буфер //---------------------------------------------------------------- for (int i = 0; i < 20; i++) { LineField(hdc,PointB[i],RGB(255,0,0),1); } for(int i=20; i<40; i++) { LineField(hdc,PointB[i],RGB(0,0,255), 1); } for (int i = 40; i<60; i++) { LineField(hdc, PointB[i], RGB(0, 255,0), 1); } //----------------------------------------------------------------------- //выводим содержимое Z-буфера в контекст памяти //-------------------------------------------------------------------- //двигаемся по всем пикселям окна вывода for (unsigned long ij=0; ij<NM; ij++) { x1 = ne1 + ij%Np; y1 = me2 + ij/Np; SetPixel(hdc,x1,y1,RGB(zb[ij].c.R,zb[ij].c.G,zb[ij].c.B)); } delete [] zb; //очищаем память под Z-буфером //------------------------------------------------------------- //рисуем координтные оси //------------------------------------------------------------------------ HPEN hPen = CreatePen(PS_SOLID,1,RGB(0,255,255)); HPEN hPenOld = (HPEN)SelectObject(hdc,hPen); int x2,y2; //ось Ox xe=Xe(-xmax/3,0,0); ye=Ye(-xmax/3,0,0); x1=xn(xe); y1=ym(ye); xe=Xe(xmax,0,0); ye=Ye(xmax,0,0); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); SetBkColor(hdc,RGB(0xC0,0xC0,0xC0)); SetTextColor(hdc,RGB(120,120,120)); TextOut(hdc,x2, y2, _T("X"),1); //Ось Oy xe=Xe(0,-ymax/3, 0); ye=Ye(0,-ymax/3,0); x1=xn(xe); y1=ym(ye); xe=Xe(0,ymax, 0); ye=Ye(0,ymax,0); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); SetBkColor(hdc,RGB(0xC0,0xC0,0xC0)); SetTextColor(hdc,RGB(120,120,120)); TextOut(hdc,x2, y2, _T("Y"),1); //Ось Oz xe=Xe(0,0, 0); ye=Ye(0,0,-zmax/3); x1=xn(xe); y1=ym(ye); xe=Xe(0,0, 0); ye=Ye(0,0,zmax); x2=xn(xe); y2=ym(ye); MoveToEx(hdc,x1,y1,NULL); LineTo(hdc,x2,y2); SetBkColor(hdc,RGB(0xC0,0xC0,0xC0)); SetTextColor(hdc,RGB(120,120,120)); TextOut(hdc,x2, y2, _T("Z"),1); SelectObject(hdc,hPenOld); DeleteObject(hPen); //----------------------------------------------------------------------------- //рисуем куб //---------------------------------------------------------------------- hPen = CreatePen(PS_SOLID,1,RGB(160,160,160)); hPenOld = (HPEN)SelectObject(hdc,hPen); DrawBox(hwnd, hdc, angl); SelectObject(hdc,hPenOld); DeleteObject(hPen); //------------------------------------------------------------------------ //копируем контекст памяти в контекст экрана //----------------------------------------------------------------------- BitBlt(hdcWin,ne1,me2-30,ne2,me1,hdc,ne1,me2-30,SRCCOPY); //---------------------------------------------------------------------- //завершаем работу с контекстами и памятью //------------------------------------------------------------------- SelectObject(hdc, hBitmapOld); //востанавливаем контекст памяти DeleteObject(hBitmap); //убираем битовую карту DeleteDC(hdc); // освобождаем контекст памяти //освобождаем контекст экрана if(Context == 1) EndPaint(hwnd, &ps); else ReleaseDC(hwnd, hdcWin); }
MOZCE_SHUNT_API int ExtSelectClipRgn(HDC inDC, HRGN inRGN, int inMode) { #ifdef API_LOGGING mozce_printf("ExtSelectClipRgn called\n"); #endif // inModes are defined as: // RGN_AND = 1 // RGN_OR = 2 // RGN_XOR = 3 // RGN_DIFF = 4 // RGN_COPY = 5 if (inMode == RGN_COPY) { return SelectClipRgn(inDC, inRGN); } HRGN cRGN = NULL; int result = GetClipRgn(inDC, cRGN); // if there is no current clipping region, set it to the // tightest bounding rectangle that can be drawn around // the current visible area on the device if (result != 1) { RECT cRect; GetClipBox(inDC,&cRect); cRGN = CreateRectRgn(cRect.left,cRect.top,cRect.right,cRect.bottom); } // now select the proper region as the current clipping region result = SelectClipRgn(inDC,cRGN); if (result == NULLREGION) { if (inMode == RGN_DIFF || inMode == RGN_AND) result = SelectClipRgn(inDC,NULL); else result = SelectClipRgn(inDC,inRGN); DeleteObject(cRGN); return result; } if (result == SIMPLEREGION || result == COMPLEXREGION) { if (inMode == RGN_DIFF) CombineRgn(cRGN, cRGN, inRGN, inMode); else CombineRgn(cRGN, inRGN, cRGN, inMode); result = SelectClipRgn(inDC,cRGN); DeleteObject(cRGN); return result; } HRGN rgn = CreateRectRgn(0, 0, 32000, 32000); result = SelectClipRgn(inDC, rgn); DeleteObject(rgn); return result; }
/* Operations to create, modify and destroy regions. */ HRGN WinCreateEmptyRgn() { return CreateRectRgn (0, 0, 1, 1); } /* WinCreateRectRgn */
// // Since the transparent color for all LiteStep modules should be 0xFF00FF and // we are going to assume a tolerance of 0x000000, we can ignore the clrTransp // and clrTolerence parameter and hard code the values for the High and Low RGB // bytes The orginial code is commented out, if a module needs the removed // functionality, it should implement this function with the commented out code. HRGN BitmapToRegion( HBITMAP hbm, COLORREF clrTransp, COLORREF clrTolerance, int xoffset, int yoffset) { // start with a completely transparent rgn // this is more correct as no bmp, should render a transparent background HRGN hRgn = CreateRectRgn(0, 0, 0, 0); if (hbm) { // create a dc for the 32 bit dib HDC hdcMem = CreateCompatibleDC(NULL); if (hdcMem) { VOID *pbits32; HBITMAP hbm32; BITMAP bm; // get the size GetObject(hbm, sizeof(BITMAP), &bm); BITMAPINFOHEADER bmpInfo32; bmpInfo32.biSize = sizeof(BITMAPINFOHEADER); bmpInfo32.biWidth = bm.bmWidth; bmpInfo32.biHeight = bm.bmHeight; bmpInfo32.biPlanes = 1; bmpInfo32.biBitCount = 32; bmpInfo32.biCompression = BI_RGB; bmpInfo32.biSizeImage = 0; bmpInfo32.biXPelsPerMeter = 0; bmpInfo32.biYPelsPerMeter = 0; bmpInfo32.biClrUsed = 0; bmpInfo32.biClrImportant = 0; hbm32 = CreateDIBSection(hdcMem, (BITMAPINFO*)&bmpInfo32, DIB_RGB_COLORS, &pbits32, NULL, 0); if (hbm32) { HBITMAP hbmOld32 = (HBITMAP)SelectObject(hdcMem, hbm32); // Create a DC just to copy the bitmap into the memory D HDC hdcTmp = CreateCompatibleDC(hdcMem); if (hdcTmp) { // Get how many bytes per row we have for the bitmap bits // (rounded up to 32 bits) BITMAP bm32; GetObject(hbm32, sizeof(bm32), &bm32); while (bm32.bmWidthBytes % 4) { ++bm32.bmWidthBytes; } #if defined(LS_COMPAT_TRANSPTOL) // get the limits for the colors BYTE clrHiR = (0xff - GetRValue(clrTolerance)) > GetRValue(clrTransp) ? GetRValue(clrTransp) + GetRValue(clrTolerance) : 0xff; BYTE clrHiG = (0xff - GetGValue(clrTolerance)) > GetGValue(clrTransp) ? GetGValue(clrTransp) + GetGValue(clrTolerance) : 0xff; BYTE clrHiB = (0xff - GetBValue(clrTolerance)) > GetBValue(clrTransp) ? GetBValue(clrTransp) + GetBValue(clrTolerance) : 0xff; BYTE clrLoR = GetRValue(clrTolerance) < GetRValue(clrTransp) ? GetRValue(clrTransp) - GetRValue(clrTolerance) : 0x00; BYTE clrLoG = GetGValue(clrTolerance) < GetGValue(clrTransp) ? GetGValue(clrTransp) - GetGValue(clrTolerance) : 0x00; BYTE clrLoB = GetBValue(clrTolerance) < GetBValue(clrTransp) ? GetBValue(clrTransp) - GetBValue(clrTolerance) : 0x00; #endif // LS_COMPAT_TRANSPTOL // Copy the bitmap into the memory D HBITMAP hbmOld = (HBITMAP)SelectObject(hdcTmp, hbm); BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcTmp, 0, 0, SRCCOPY); // Scan each bitmap row from bottom to top // (the bitmap is inverted vertically) #if defined(LS_COMPAT_TRANSPTOL) BYTE *p; #else DWORD *p; #endif // LS_COMPAT_TRANSPTOL BYTE *p32 = (BYTE *)bm32.bmBits + \ (bm32.bmHeight - 1) * bm32.bmWidthBytes; int y = 0; while (y < bm.bmHeight) { int x = 0, x0; while (x < bm.bmWidth) { // loop through all transparent pixels... while (x < bm.bmWidth) { #if defined(LS_COMPAT_TRANSPTOL) p = p32 + 4 * x; // if the pixel is non-transparent, then break if (*p < clrLoB || *p > clrHiB) { break; } ++p; if (*p < clrLoG || *p > clrHiG) { break; } ++p; if (*p < clrLoR || *p > clrHiR) { break; } #else p = (DWORD*)(p32 + 4 * x); if (*p != 0xFF00FF) { break; } #endif // LS_COMPAT_TRANSPTOL ++x; } // save first non transparent pixel offset x0 = x; // loop through all non transparent pixels while (x < bm.bmWidth) { #if defined(LS_COMPAT_TRANSPTOL) p = p32 + 4 * x; // if the pixel is transparent, then break if (*p >= clrLoB && *p <= clrHiB) { ++p; if (*p >= clrLoG && *p <= clrHiG) { ++p; if (*p >= clrLoR && *p <= clrHiR) { break; } } } #else p = (DWORD*)(p32 + 4 * x); if (*p == 0xFF00FF) { break; } #endif // LS_COMPAT_TRANSPTOL ++x; } // if found one or more non-transparent pixels in a // row, add them to the rgn... if ((x - x0) > 0) { HRGN hTempRgn = CreateRectRgn( x0 + xoffset, y + yoffset, x + xoffset, y + 1 + yoffset); CombineRgn(hRgn, hRgn, hTempRgn, RGN_OR); DeleteObject(hTempRgn); } ++x; } ++y; p32 -= bm32.bmWidthBytes; } // Clean up SelectObject(hdcTmp, hbmOld); DeleteDC(hdcTmp); } SelectObject(hdcMem, hbmOld32); DeleteObject(hbm32); } DeleteDC(hdcMem); } } return hRgn; }
HRGN WinXorRgn (HRGN hrgnSrc1, HRGN hrgnSrc2) { HRGN hrgnDest = CreateRectRgn(0, 0, 1, 1); CombineRgn(hrgnDest, hrgnSrc1, hrgnSrc2, RGN_XOR); return hrgnDest; } /* WinXorRgn */
HWND MetaTaskbar::createTaskSw(ULONG id, ULONG state) { vnclog.Print(1, _T("%s: id=0x%X state=0x%X\n"), __FUNCTION__, id, state); char className[TaskSwClassNameLen]; sprintf(className, TaskSwClassNameTemplate, id); // Create a dummy window to handle taskbar messages WNDCLASSEX wndclass; wndclass.cbSize = sizeof(wndclass); wndclass.style = 0; wndclass.lpfnWndProc = MetaTaskbar::WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = m_pApp->m_instance; wndclass.hIcon = NULL; wndclass.hCursor = NULL; wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = (const char *) NULL; wndclass.lpszClassName = className; wndclass.hIconSm = NULL; RegisterClassEx(&wndclass); HWND hwnd = CreateWindow(className, className, WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX, 0, 0, 0, 0, NULL, NULL, m_pApp->m_instance, NULL); if (hwnd == NULL) { vnclog.Print(0, TEXT("MetaTaskbar : ERROR : failed to create task switch window\n")); return NULL; } HRGN hRgn = CreateRectRgn(0, 0, 0, 0); SetWindowRgn(hwnd, hRgn, FALSE); // set this window transparent SetWindowLong(hwnd, GWL_USERDATA, (LONG) this); HMENU hsysmenu = GetSystemMenu(hwnd, FALSE); if (hsysmenu == NULL) { vnclog.Print(0, TEXT("MetaTaskbar : ERROR : failed to get system menu of task switch window\n")); } else { RemoveMenu(hsysmenu, SC_SIZE, MF_BYCOMMAND); RemoveMenu(hsysmenu, SC_MOVE, MF_BYCOMMAND); } taskbarControl(hwnd, TASKBAR_ADD); TaskSwState tswstate; tswstate.hwnd = hwnd; tswstate.state = state; omni_mutex_lock l(m_taskSwitchesLock); m_taskSwitches.insert(IdStateMap::value_type(id, tswstate)); if (state & rfbWindowStateMinimized) ShowWindow(hwnd, SW_MINIMIZE); else if (state & rfbWindowStateMaximized) ShowWindow(hwnd, SW_MAXIMIZE); return hwnd; }
void CSonicSkin::SetRgn(RECT * pRect /* = NULL */, BOOL bDraw /* = TRUE */) { if(m_bg.nColorKey < 0) { return; } static BOOL bEnter = FALSE; if(bEnter) { return; } bEnter = TRUE; CRect rtClient; if(pRect == NULL) { GetClientRect(m_hWnd, &rtClient); } else { rtClient = *pRect; } const int nCorner = 20; HRGN hOldRgn = m_bg.hMainRgn; m_bg.hMainRgn = CreateRectRgn(0, 0, rtClient.Width(),rtClient.Height()); CRect rtSrc; // left top corner rtSrc.SetRect(0, 0, nCorner, nCorner); m_bg.hRgn[0] = m_bg.pImg->CreateRgn(m_bg.nColorKey, 0, 0, &rtSrc, TRUE); CombineRgn(m_bg.hMainRgn, m_bg.hMainRgn, m_bg.hRgn[0], RGN_XOR); // right top corner rtSrc.SetRect(m_bg.pImg->GetWidth() - nCorner, 0, m_bg.pImg->GetWidth(), nCorner); m_bg.hRgn[1] = m_bg.pImg->CreateRgn(m_bg.nColorKey, rtClient.Width() - nCorner, 0, &rtSrc, TRUE); CombineRgn(m_bg.hMainRgn, m_bg.hMainRgn, m_bg.hRgn[1], RGN_XOR); // left bottom corner rtSrc.SetRect(0, m_bg.pImg->GetHeight() - nCorner, nCorner, m_bg.pImg->GetHeight()); m_bg.hRgn[2] = m_bg.pImg->CreateRgn(m_bg.nColorKey, 0, rtClient.Height() - nCorner, &rtSrc, TRUE); CombineRgn(m_bg.hMainRgn, m_bg.hMainRgn, m_bg.hRgn[2], RGN_XOR); // right bottom corner rtSrc.SetRect(m_bg.pImg->GetWidth() - nCorner, m_bg.pImg->GetHeight() - nCorner, m_bg.pImg->GetWidth(), m_bg.pImg->GetHeight()); m_bg.hRgn[3] = m_bg.pImg->CreateRgn(m_bg.nColorKey, rtClient.Width() - nCorner, rtClient.Height() - nCorner, &rtSrc, TRUE); CombineRgn(m_bg.hMainRgn, m_bg.hMainRgn, m_bg.hRgn[3], RGN_XOR); SetWindowRgn(m_hWnd, m_bg.hMainRgn, bDraw); for(int i = 0; i < 4; i++) { if(m_bg.hRgn[i]) { DeleteObject(m_bg.hRgn[i]); m_bg.hRgn[i] = NULL; } } if(hOldRgn) { DeleteObject(hOldRgn); } bEnter = FALSE; }
// static HRGN Path::CombineRegions(HRGN r1, HRGN r2) { HRGN dest = CreateRectRgn(0, 0, 1, 1); CombineRgn(dest, r1, r2, RGN_OR); return dest; }
void TfrmMain::wmTimer(WPARAM wParam, LPARAM lParam) { if (wParam == ID_bvlTarget) { // Timer for Target selector static int primarymouse; if(!m_hTargetHighlighter) { primarymouse=GetSystemMetrics(SM_SWAPBUTTON)?VK_RBUTTON:VK_LBUTTON; m_hTargetHighlighter=CreateWindowEx(WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOOLWINDOW,(LPTSTR)g_clsTargetHighlighter,NULL,WS_POPUP,0,0,0,0,NULL,NULL,hInst,NULL); if(!m_hTargetHighlighter) return; SetLayeredWindowAttributes(m_hTargetHighlighter,0,123,LWA_ALPHA); SetSystemCursor(CopyCursor(IcoLib_GetIcon(ICO_PLUG_SSTARGET)),OCR_NORMAL); Hide(); } if(!(GetAsyncKeyState(primarymouse)&0x8000)) { KillTimer(m_hWnd,ID_bvlTarget); SystemParametersInfo(SPI_SETCURSORS,0,NULL,0); DestroyWindow(m_hTargetHighlighter),m_hTargetHighlighter=NULL; SetTargetWindow(m_hTargetWindow); Show(); return; } POINT point; GetCursorPos(&point); m_hTargetWindow=WindowFromPoint(point); if(!((GetAsyncKeyState(VK_SHIFT)|GetAsyncKeyState(VK_MENU))&0x8000)) for(HWND hTMP; (hTMP=GetParent(m_hTargetWindow)); m_hTargetWindow=hTMP); if(m_hTargetWindow!=m_hLastWin) { m_hLastWin=m_hTargetWindow; RECT rect; GetWindowRect(m_hLastWin,&rect); int width=rect.right-rect.left; int height=rect.bottom-rect.top; if(g_iTargetBorder) { SetWindowPos(m_hTargetHighlighter,NULL,0,0,0,0,SWP_HIDEWINDOW|SWP_NOMOVE|SWP_NOSIZE); if(width>g_iTargetBorder*2 && height>g_iTargetBorder*2) { HRGN hRegnNew=CreateRectRgn(0,0,width,height); HRGN hRgnHole=CreateRectRgn(g_iTargetBorder,g_iTargetBorder,width-g_iTargetBorder,height-g_iTargetBorder); CombineRgn(hRegnNew,hRegnNew,hRgnHole,RGN_XOR); DeleteObject(hRgnHole); SetWindowRgn(m_hTargetHighlighter,hRegnNew,FALSE);//cleans up hRegnNew } else SetWindowRgn(m_hTargetHighlighter,NULL,FALSE); } SetWindowPos(m_hTargetHighlighter,HWND_TOPMOST,rect.left,rect.top,width,height,SWP_SHOWWINDOW|SWP_NOACTIVATE); } return; } if (wParam == ID_chkTimed) { // Timer for Screenshot #ifdef _DEBUG OutputDebugStringA("SS Bitmap Timer Start\r\n" ); #endif if(!m_bCapture) { //only start once if (m_Screenshot) { FIP->FI_Unload(m_Screenshot); m_Screenshot = NULL; } m_bCapture = true; switch (m_opt_tabCapture) { case 0: m_Screenshot = CaptureWindow(m_hTargetWindow, m_opt_chkClientArea); break; case 1: m_Screenshot = CaptureMonitor((m_opt_cboxDesktop > 0) ? m_Monitors[m_opt_cboxDesktop-1].szDevice : NULL); break; default: KillTimer(m_hWnd,ID_chkTimed); m_bCapture = false; #ifdef _DEBUG OutputDebugStringA("SS Bitmap Timer Stop (no tabCapture)\r\n" ); #endif return; } if (!m_Screenshot) m_bCapture = false; } if (m_Screenshot) { KillTimer(m_hWnd,ID_chkTimed); m_bCapture = false; #ifdef _DEBUG OutputDebugStringA("SS Bitmap Timer Stop (CaptureDone)\r\n" ); #endif SendMessage(m_hWnd,UM_EVENT, 0, (LPARAM)EVT_CaptureDone); } } }