static BOOL IsGDIDriver(HDC hDC) { COLORREF NearestBlack = GetNearestColor(hDC, RGB(0, 0, 0)); COLORREF NearestWhite = GetNearestColor(hDC, RGB(255, 255, 255)); if (NearestBlack != RGB(0, 0, 0) || NearestWhite != RGB(255, 255, 255)) return TRUE; return FALSE; }
COLORREF Draw::GetColor(Color c) const { COLORREF color = c; #ifdef PLATFORM_WINCE return color; #else if(!palette) return color; static Index<dword> *SColor; ONCELOCK { static Index<dword> StaticColor; StaticColor << RGB(0x00, 0x00, 0x00) << RGB(0x80, 0x00, 0x00) << RGB(0x00, 0x80, 0x00) << RGB(0x80, 0x80, 0x00) << RGB(0x00, 0x00, 0x80) << RGB(0x80, 0x00, 0x80) << RGB(0x00, 0x80, 0x80) << RGB(0xC0, 0xC0, 0xC0) << RGB(0xC0, 0xDC, 0xC0) << RGB(0xA6, 0xCA, 0xF0) << RGB(0xFF, 0xFB, 0xF0) << RGB(0xA0, 0xA0, 0xA4) << RGB(0x80, 0x80, 0x80) << RGB(0xFF, 0x00, 0x00) << RGB(0x00, 0xFF, 0x00) << RGB(0xFF, 0xFF, 0x00) << RGB(0x00, 0x00, 0xFF) << RGB(0xFF, 0x00, 0xFF) << RGB(0x00, 0xFF, 0xFF) << RGB(0xFF, 0xFF, 0xFF); SColor = &StaticColor; } if(color16 || !AutoPalette()) return GetNearestColor(handle, color); if(SColor->Find(color) >= 0) return color; if(color == sLightGray) return PALETTEINDEX(216 + 17); int r = GetRValue(color); int g = GetGValue(color); int b = GetBValue(color); return PALETTEINDEX(r == g && g == b ? (r + 8) / 16 + 216 : (r + 25) / 51 * 36 + (g + 25) / 51 * 6 + (b + 25) / 51); #endif }
static void drawUnselected( HDC hdc, int x, int y ) { RECT rect; HBRUSH hColourBrush; COLORREF nearest; rect.left = 0; rect.top = 0; rect.right = WIDTH * NUM_ACROSS; rect.bottom = HEIGHT * NUM_DOWN; MapDialogRect( hColorbar, &rect ); Width = (rect.right - rect.left) / NUM_ACROSS; Height = (rect.bottom - rect.top) / NUM_DOWN; rect.left = x * Width + SPC; rect.top = y * Height + SPC; rect.right = (x + 1) * Width - SPC; rect.bottom = (y + 1) * Height - SPC; // MapDialogRect( hColorbar, &rect ); nearest = GetNearestColor( hdc, RGBValues[y * NUM_ACROSS + x] ); hColourBrush = CreateSolidBrush( nearest ); FillRect( hdc, &rect, hColourBrush ); drawFocus( hdc, &rect, false ); DeleteObject( hColourBrush ); }
void InitSysColors(void) { char KeyNames[1024]; char KeyColor[128]; LPSTR lpKey; LPSTR lpFile; int n,ret; COLORREF sc; COLORREF rc; HDC hDC; lpFile = GetTwinFilename(); GetPrivateProfileString((LPSTR)"colors",NULL,NULL, KeyNames,1024,lpFile); hDC = GetDC(0); for(lpKey = KeyNames; *lpKey != 0; lpKey += strlen(lpKey) + 1) for(n=0; SysColorNames[n]; n++) if(strcasecmp(SysColorNames[n],lpKey) == 0) { sc = GetSysColor(n); ret = GetPrivateProfileString( (LPSTR)"colors", (LPSTR) lpKey, (LPSTR) 0, KeyColor, 128, lpFile); if (ret) { rc = GetStringColor(KeyColor); switch (n) { case COLOR_MENU: case COLOR_WINDOW: case COLOR_BTNFACE: case COLOR_HIGHLIGHT: case COLOR_MENUTEXT: case COLOR_WINDOWTEXT: case COLOR_CAPTIONTEXT: case COLOR_HIGHLIGHTTEXT: case COLOR_BTNTEXT: /* those cannot be dithered */ rc = GetNearestColor(hDC,rc); break; default: break; } SetSysColors(1,&n,&rc); break; } } ReleaseDC(0,hDC); }
void MDIORGB_GetColour (COLOR pmColour, OOTreal *pmRed, OOTreal *pmGreen, OOTreal *pmBlue) { COLORREF myColourDisplayed; myColourDisplayed = GetNearestColor ( MIO_selectedRunWindowInfo -> deviceContext, (COLORREF) pmColour); *pmRed = (double) GetRValue (myColourDisplayed) / 255; *pmGreen = (double) GetGValue (myColourDisplayed) / 255; *pmBlue = (double) GetBValue (myColourDisplayed) / 255; } // MDIORGB_GetColour
COLOR MDIORGB_ConvertColour (OOTint pmClrNum) { COLORREF myBaseColour, myDesiredColour; BYTE myRed, myGreen, myBlue; if (!MIO_selectedRunWindowInfo -> xor) { return (COLOR) PALETTEINDEX (pmClrNum); } // Gets ugly - Handle XOR // The main problem is that Windows can draw in XOR mode, but it uses the // pixel values. This means that if we want XOR to work with a particular // colour value (i.e. drawing on top of colour x comes out in the original // colour, then one a direct colour display we need to XOR the RGB of the // colour we want to draw with the RGB of colour x, and then draw the line // in XOR mode in the resulting colour. // With a CLUT display, it's even more complicated. We need to find out // the index to the actual display CLUT used by colour x. We then XOR it // with the index of the colour we're drawing in. We then get an index // number to the actual display CLUT that we want to use. We then have to // figure out what RGB or palette index will correspond to that index in // the display CLUT. // For direct colour myBaseColour = GetNearestColor ( MIO_selectedRunWindowInfo -> deviceContext, (COLORREF) PALETTEINDEX (0)); myDesiredColour = GetNearestColor ( MIO_selectedRunWindowInfo -> deviceContext, (COLORREF) PALETTEINDEX (pmClrNum)); myRed = GetRValue (myBaseColour) ^ GetRValue (myDesiredColour); myGreen = GetGValue (myBaseColour) ^ GetGValue (myDesiredColour); myBlue = GetBValue (myBaseColour) ^ GetBValue (myDesiredColour); return (COLOR) RGB (myRed, myGreen, myBlue); } // MDIORGB_ConvertColour
void CPreviewDC::MirrorAttributes() { ASSERT(m_hAttribDC != NULL); if (m_hDC != NULL) { // extract and re-set Pen and Brush HGDIOBJ hTemp = ::SelectObject(m_hAttribDC, ::GetStockObject(BLACK_PEN)); ::SelectObject(m_hAttribDC, hTemp); ::SelectObject(m_hDC, hTemp); hTemp = ::SelectObject(m_hAttribDC, ::GetStockObject(BLACK_BRUSH)); ::SelectObject(m_hAttribDC, hTemp); ::SelectObject(m_hDC, hTemp); SetROP2(GetROP2()); SetBkMode(GetBkMode()); SetTextAlign(GetTextAlign()); SetPolyFillMode(GetPolyFillMode()); SetStretchBltMode(GetStretchBltMode()); SetTextColor(GetNearestColor(GetTextColor())); SetBkColor(GetNearestColor(GetBkColor())); } }
LRESULT CWindow::OnPaint(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int iLineCount, iColumnCount; PAINTSTRUCT ps; BeginPaint(hWnd, &ps); iLineCount = cyClient / cyChar; iColumnCount = cxClient / cxChar; SelectObject(ps.hdc, m_hFont); for (UInt32 i = 0, j = min(countof(szErrorString), iLineCount); i != j; ++i) { int len = lstrlen(szErrorString[i + iVScrollPos]); if (i + iVScrollPos < countof(szErrorString)) { TextOut(ps.hdc, 10, i * cyChar, szErrorString[i + iVScrollPos], min(len, iColumnCount)); } } PBYTE pbBuffer; DWORD dwSize; GLYPHMETRICS gm; MAT2 m2 = { {0, 1}, {0, 0}, {0, 0}, {0, 1} }; BYTE m_matrix[32]; char buf[100]; dwSize = GetGlyphOutlineA(ps.hdc, 0xB8DF, GGO_BITMAP, &gm, 0, NULL, &m2); if (dwSize != GDI_ERROR) { pbBuffer = (PBYTE)malloc(dwSize); GetGlyphOutlineA(ps.hdc, 0xB8DF, GGO_BITMAP, &gm, dwSize, pbBuffer, &m2); for(DWORD i = 0; i < dwSize / 4; ++i) { m_matrix[i*2] = pbBuffer[4*i]; m_matrix[i*2+1] = pbBuffer[4*i+1]; wsprintf(buf, "0x%02X 0x%02X", m_matrix[i*2], m_matrix[i*2+1]); } free(pbBuffer); } wsprintf(buf, "%d", GetDeviceCaps(ps.hdc, PLANES) * GetDeviceCaps(ps.hdc, BITSPIXEL)); SetWindowText(hWnd, buf); GetNearestColor(ps.hdc, RGB(123, 321, 123)); EndPaint(hWnd, &ps); return ERROR_SUCCESS; }
void CWinApp::SetDialogBkColor(COLORREF clrCtlBk, COLORREF clrCtlText) { if (!afxContextIsDLL) { _AFX_THREAD_STATE* pThreadState = AfxGetThreadState(); if (pThreadState->m_hHookOldCbtFilter == NULL) { pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT, _AfxCbtFilterHook, NULL, ::GetCurrentThreadId()); if (pThreadState->m_hHookOldCbtFilter == NULL) AfxThrowMemoryException(); } } // set up for grey backgrounds for dialogs _AFX_WIN_STATE* pWinState = _afxWinState; AfxDeleteObject((HGDIOBJ*)&pWinState->m_hDlgBkBrush); #ifdef _MAC // MFC's default gray color is available in the VGA palette but not in // the standard Mac 4- or 8-bit color tables, so we will remap it to // the closest available solid color. We also want to use 3DLIGHT or BTNFACE // as the background color rather than the darker gray that Win32 MFC uses. if (clrCtlBk == RGB(192, 192, 192)) { DWORD dwFlags; SystemParametersInfo(SPI_GET3D, 0, (LPVOID) &dwFlags, 0); UINT nColor = (dwFlags & F3D_OFFICE3D) ? COLOR_3DFACE : COLOR_3DLIGHT; HDC hdc = ::GetDC(NULL); clrCtlBk = GetNearestColor(hdc, GetSysColor(nColor)); ::ReleaseDC(NULL, hdc); } // save the requested background color pWinState->m_crDlgBkClr = clrCtlBk; #endif pWinState->m_hDlgBkBrush = ::CreateSolidBrush(clrCtlBk); pWinState->m_crDlgTextClr = clrCtlText; if (pWinState->m_hDlgBkBrush == NULL) AfxThrowResourceException(); }
STATICFN DWORD NEAR MyGetNearestColor( DWORD rgb, BOOL fMonoOK) { HDC hdc; HDC hdcMem; DWORD rgbNearest; HBITMAP hbmMem; HBITMAP hbmOld; hdc = GetDC(ghwndMain); hdcMem = CreateCompatibleDC(hdc); hbmMem = MyCreateBitmap(hdc, 1, 1, (fMonoOK) ? gnColorPalColors : 16); hbmOld = SelectObject(hdcMem, hbmMem); rgbNearest = GetNearestColor(hdcMem, rgb); SelectObject(hdcMem, hbmOld); DeleteObject(hbmMem); DeleteDC(hdcMem); ReleaseDC(ghwndMain, hdc); return rgbNearest; }
COLORREF GetBrowserSelectionColor(HDC hDC) { char color[64]; WORD wRed, wGreen, wBlue; char *end; if (selection_color != -1) return (COLORREF) selection_color; KppGetKappaIniFile(return_buffer, RET_BUFFER_LEN); GetPrivateProfileString("Browser", "SelectionColor", "Red", color, 64, return_buffer); GetPrivateProfileString("Colors", color, "255,0,0", color, 64, return_buffer); wRed = (WORD) strtol(color, &end, 10); while (!isdigit(*end) && *end) ++end; wGreen = (WORD) strtol(color + (end - color), &end, 10); while (!isdigit(*end) && *end) ++end; wBlue = (WORD) strtol(color + (end - color), &end, 10); return selection_color = GetNearestColor(hDC, RGB(wRed, wGreen, wBlue)); }
void CSliderCtrlEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) { int loopMax = colorList.GetSize(); // number of color ranges to process LPNMCUSTOMDRAW lpCustDraw = (LPNMCUSTOMDRAW)pNMHDR; //////////////////////////////////////////////////////////////////////////////// // OnCustomDraw() is called at many different stages during the painting process // of the control. We only care about the PREPAINT state or the ITEMPREPAINT // state and not always then. // // If we want to be notified about subcontrol painting, we have to say so when // we get the initial PREPAINT message. //////////////////////////////////////////////////////////////////////////////// if(lpCustDraw->dwDrawStage == CDDS_PREPAINT) { // should we report slider's position? int curVal = GetPos(); if((m_Callback != NULL) && (curVal != m_oldPosition)) { m_oldPosition = curVal; m_Callback(m_p2Object, m_data1, curVal, m_IsDragging); } // If we don't have any special coloring to do, skip all the silliness... if(loopMax <= 0) { *pResult = CDRF_DODEFAULT; } else { // We want to be informed when each part of the control is being // processed so we can intercept the channel drawing. *pResult = CDRF_NOTIFYITEMDRAW; // send messages for each piece-part } return; } /////////////////////////////////////////////////////////////////////////////// // A slider (track control) is drawn in several steps: // 1. Erase // 2. Tics // 3. Channel // 4. Thumb // // It would be nice to capture when the background has been painted and // before the other sub-pieces have been painted. Then we could just // substitute our own painting routine. But this doesn't seem to be // available. // // So this routine captures the tics by inserting operations before // painting the thumb. // // Look at the help on NMCUSTOMDRAW for complete details, but the pNMHDR // pointer looks at a structure like: // // typedef struct tagNMCUSTOMDRAWINFO { // NMHDR hdr; // DWORD dwDrawStage; // This indicates what stage of the drawing process is involved // HDC hdc; // graphics context of the control (or sub-component) // RECT rc; // DWORD dwItemSpec; // This is the particular piece-part of the slider involved // UINT uItemState; // LPARAM lItemlParam; // } NMCUSTOMDRAW // // The stages include CDDS_PREPAINT, which is just before painting of the entire // control. However, unless the *pResult parameter is set to CDRF_NOTIFYITEMDRAW, // we will get notification for the control as a whole, not for each piece-part. // So the first thing to do is set *pResult. Thereafter, we must intercept // the sub-parts. // // We don't care about painting the background (we will re-paint later on). We // don't care about PREPAINT on the CHANNEL or the TICS since we will overwrite // everything when we get to the THUMB. ///////////////////////////////////////////////////////////////////////////////// if((lpCustDraw->dwDrawStage == CDDS_ITEMPREPAINT) && (lpCustDraw->dwItemSpec != TBCD_THUMB)) { *pResult = CDRF_DODEFAULT; return; } // get channel orientation BOOL IsVertical = (TBS_VERT & GetStyle()) ? TRUE : FALSE; // Get the coordinates of the control's window CRect crect; GetClientRect(crect); // client coordinates (top = left = 0, bottom = height, right = width) // Much of this is "paraphrased" from Nic Wilson's work -- see the header file ////////////////////////////////////////////////////////////////////////////////// // This bit does the tics marks transparently. // Create a memory dc to hold a copy of the oldbitmap data that includes the tics, // because when we add the background in we will lose the tic marks. /////////////////////////////////////////////////////////////////////////////////// CDC *pDC = CDC::FromHandle(lpCustDraw->hdc); CDC SaveCDC; CBitmap SaveCBmp; //set the colours for the monochrome mask bitmap COLORREF crOldBack = pDC->SetBkColor(RGB(0,0,0)); // set to Black COLORREF crOldText = pDC->SetTextColor(RGB(255,255,255)); // set to White int iWidth = crect.Width(); // channel width int iHeight = crect.Height(); // channel height //////////////////////////////////////////////////////////////////////////// // Create an in-memory copy of displayed bitmap, including the tics. // This is a monochrome bitmap since it was created from a memory DC. // If it had been created from pDC (an actual device DC, not a memory // DC) then this would be something with 8, 16, 24, or 32 bits per pixel. // // This will have a black background, with the tic marks in white. // // For reasons I don't yet understand, this saves only the tic marks and // the channel's centerline (both originally in black), and not the other // colors (such as drawn AROUND the channel's centerline). I am not sure // what would have happened if the tic marks were not black... //////////////////////////////////////////////////////////////////////////// SaveCDC.CreateCompatibleDC(pDC); SaveCBmp.CreateCompatibleBitmap(&SaveCDC, iWidth, iHeight); CBitmap* SaveCBmpOld = (CBitmap *)SaveCDC.SelectObject(SaveCBmp); SaveCDC.BitBlt(0, 0, iWidth, iHeight, pDC, crect.left, crect.top, SRCCOPY); if(m_dumpBitmaps) // debugging stuff { SaveBitmap("MonoTicsMask.bmp",SaveCBmp); } // Do as much of this stuff in memory as possible, then blit it to the screen CDC memDC; memDC.CreateCompatibleDC(pDC); CBitmap memBM; memBM.CreateCompatibleBitmap(pDC,iWidth,iHeight); // create from pDC, not memDC CBitmap *oldbm = memDC.SelectObject(&memBM); //////////////////////////////////////////////////////////////////////////////// // copy screen bitmap to memory bitmap for manipulation. If this is the very // first time the control has been updated, the screen bitmap will show only // the tic marks (in black) and the default background color (RGB(214,207,189)). // If the control has been updated before, remnants of the previously drawn // background color ranges will also show up. //////////////////////////////////////////////////////////////////////////////// memDC.BitBlt(0,0,iWidth,iHeight,pDC,0,0,SRCCOPY); if(m_dumpBitmaps) // debugging { SaveBitmap("ScrnStart.bmp",memBM); } ///////////////////////////////////////////////////////////////////////////// // Color parts of the channel if necessary. It SHOULD be necessary since we // don't get notifications unless there are colors to print, but we may have // a race condition and it is best to check. ///////////////////////////////////////////////////////////////////////////// if(loopMax) { ///////////////////////////////////////////////////////////////////////////////// // We need to draw colors over the subrange of the channel that the center of the // thumb traverses, rather than the entire client window. Later on, extend these // colors outwards to the ends of the client window (for nicer appearance). This // allows for more precise correlation with color and thumb position. ///////////////////////////////////////////////////////////////////////////////// CRect chanRect; GetChannelRect(&chanRect); CRect thmbRect; GetThumbRect(&thmbRect); // For unknown reasons, GetChannelRect() returns a rectangle // as though it were a horizonally oriented slider, even if it isn't! if(IsVertical) { CRect n; // could probably just change chanRect directly n.left = chanRect.top; n.right = chanRect.bottom; n.top = chanRect.left; n.bottom = chanRect.right; n.NormalizeRect(); chanRect.CopyRect(&n); } // Offset into client rectangle for beginning of coloring range int Offset = chanRect.left + thmbRect.Width()/2; if(IsVertical) { Offset = chanRect.top + thmbRect.Height()/2; } // Range for center of thumb on the channel int ht = chanRect.Height() - thmbRect.Height(); int wd = chanRect.Width() - thmbRect.Width(); // scaling between control range and bitmap int min,max; GetRange(min,max); // range of values for the slider double scale = (double(max) - double(min))/double(IsVertical ? ht : wd); BOOL gotStartColor = FALSE; BOOL gotEndColor = FALSE; COLORREF startColor = 0, endColor = 0; int loop; // Loop through the array of color ranges for(loop = 0; loop < loopMax; loop++) { clrRange clr; clr = colorList[loop]; // Get the good values. If not set, then entire range is good int lval = clr.lval; int hval = clr.hval; if((lval < min) || (lval > max)) lval = min; if((hval > max) || (hval < min)) hval = max; if(lval == min) { gotStartColor = TRUE; startColor = clr.strColor; } if(hval == max) { gotEndColor = TRUE; endColor = clr.endColor; } int minVal = lval - min; // offset into bitmap for this color minVal = int(double(minVal)/scale); // width (or height for vertical slider) inside bitmap for this color int widthVal = hval - lval; widthVal = int((double(widthVal)/scale) + 1.0); // For drawing a gradient, we need to know the individual RGB values int sR,eR,sG,eG,sB,eB; // start and end R, G, and B values sR = GetRValue(clr.strColor); eR = GetRValue(clr.endColor); sG = GetGValue(clr.strColor); eG = GetGValue(clr.endColor); sB = GetBValue(clr.strColor); eB = GetBValue(clr.endColor); if(GradientFill != NULL) { TRIVERTEX vert[2]; // for specifying range to gradient fill GRADIENT_RECT gRect; // Warning C4244: conversion from 'int' to 'unsigned short', possible loss of data #pragma warning (push) #pragma warning (disable : 4244) vert[0].Red = sR<<8; // expects 16-bit color values! vert[0].Green = sG<<8; vert[0].Blue = sB<<8; vert[0].Alpha = 0; // no fading/transparency vert[1].Red = eR<<8; vert[1].Green = eG<<8; vert[1].Blue = eB<<8; vert[1].Alpha = 0; #pragma warning (pop) gRect.UpperLeft = 0; gRect.LowerRight = 1; BOOL retval; if(IsVertical) // vertically oriented? { vert[0].x = 0; vert[0].y = Offset + minVal; vert[1].x = iWidth; vert[1].y = Offset + minVal + widthVal; retval = GradientFill(memDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_V); } else { vert[0].x = Offset + minVal; vert[0].y = 0; vert[1].x = Offset + minVal + widthVal; vert[1].y = iHeight; retval = GradientFill(memDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_H); } } else { // Homebrew version of GradientFill for rectangles -- works pretty well, sort of. int i; for(i = 0; i < widthVal; i++) // for each pixel column in bitmap color range { int R = sR; int G = sG; int B = sB; if(widthVal) { R += ::MulDiv(eR - sR, i, widthVal); G += ::MulDiv(eG - sG, i, widthVal); B += ::MulDiv(eB - sB, i, widthVal); } if(IsVertical) { // widthVal really refers to height //memDC.FillSolidRect(0,minVal+i,iWidth,widthVal-i,GetNearestColor(memDC,RGB(R,G,B))); memDC.FillSolidRect( 0, // starting X value Offset + minVal + i, // starting Y value iWidth, // full width 1, // one pixel height GetNearestColor(memDC,RGB(R,G,B))); } else { //memDC.FillSolidRect(minVal+i,0,widthVal-i,iHeight,GetNearestColor(memDC,RGB(R,G,B))); memDC.FillSolidRect( Offset + minVal + i, // Starting X value 0, // Starting Y value 1, // 1 pixel wide iHeight, // full height GetNearestColor(memDC,RGB(R,G,B))); } } } } if(m_extendColors) { // If we have put in colors at the slider ends, then extend those same // colors to the rest of the background. We could try to determine the // colors by examining the bitmap, but this is awkward and it is just // as easy to grab them on-the-fly in the coloring loop above. // // If you want to see why this is done, just set m_extendColors to FALSE // and take a look at the control. Ugly. But there might be a legitimate // reason for it so leave the option to suppress. if(IsVertical) { if(gotStartColor) { memDC.FillSolidRect(0, 0, iWidth, Offset, startColor); } if(gotEndColor) { memDC.FillSolidRect(0, iHeight - Offset - 1, iWidth, Offset, endColor); } } else { if(gotStartColor) { memDC.FillSolidRect(0, 0, Offset, iHeight, startColor); } if(gotEndColor) { memDC.FillSolidRect(iWidth - Offset - 1, 0, Offset, iHeight, endColor); } } } } // The screen bitmap should now have only the color ranges filled in, no tic // marks should be visible. if(m_dumpBitmaps) // debugging { SaveBitmap("ScrnColors.bmp",memBM); } ////////////////////////////////////////////////////////////// // More "paraphrasing" from Nic Wilson's work... ////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// // At this point, memDC's bitmap contains just the color ranges drawn above. // No tic marks are visible. Doing SRCINVERT with the mask will draw in the // tic marks, but all the colors will be backwards. Also, the tics will be // whatever color was drawn in the color range stuff, rather than solid, // normal tic marks. SRCINVERT means the RGB values are changed by subtracting // from 255: // // RGB(255,0,0) --> RGB(0,255,255) // RGB(247,8,0) --> RGB(8,247,255) // RGB(214,40,255) --> RGB(41,215,0) // ///////////////////////////////////////////////////////////////////////////// memDC.SetBkColor(pDC->GetBkColor()); memDC.SetTextColor(pDC->GetTextColor()); memDC.BitBlt(0, 0, iWidth, iHeight, &SaveCDC, 0, 0, SRCINVERT); if(m_dumpBitmaps) // debugging { SaveBitmap("ScrnInvert.bmp",memBM); } // Change the tic marks from the color range to the background color. This // changes only the tic marks (and the channel centerline) and leaves the // rest alone. The tic marks wind up black. memDC.BitBlt(0, 0, iWidth, iHeight, &SaveCDC, 0, 0, SRCAND); if(m_dumpBitmaps) // debugging { SaveBitmap("ScrnAnd.bmp",memBM); } // Finally, invert the color ranges to their normal values. Since the tic // marks in the SaveCDC bitmap are white, they get inverted to black. memDC.BitBlt(0, 0, iWidth, iHeight, &SaveCDC, 0, 0, SRCINVERT); if(m_dumpBitmaps) // debugging { SaveBitmap("ScrnFinal.bmp",memBM); } // Now copy out to screen pDC->BitBlt(0,0,iWidth,iHeight,&memDC,0,0,SRCCOPY); // restore and clean up pDC->SetBkColor(crOldBack); pDC->SetTextColor(crOldText); DeleteObject(SelectObject(SaveCDC, SaveCBmpOld)); DeleteDC(SaveCDC); DeleteObject(SelectObject(memDC,oldbm)); DeleteDC(memDC); *pResult = CDRF_DODEFAULT; m_dumpBitmaps = FALSE; // only do this once! }
/**************************************************************** * VOID NEAR PASCAL * Draw3DLine1( HDC hDC, UINT x, UINT y, UINT uiLen, UINT uiFlags ) * * Description: * * Does the same thing astdDraw3DLine but for single width lines. * * Comments: * ****************************************************************/ VOID NEAR PASCAL Draw3DLine1( HDC hDC, UINT x, UINT y, UINT uiLen, UINT uiFlags ) { BOOL fDark ; RECT rc ; COLORREF rgbOld ; if ( uiFlags & DRAW3D_TOPLINE ) { rc.left = x ; rc.right = rc.left + uiLen - 1 ; rc.top = y ; rc.bottom = y + 1 ; fDark = ( uiFlags & DRAW3D_IN ) ? TRUE : FALSE ; } /* possibly the bottom? */ else if ( uiFlags & DRAW3D_BOTTOMLINE ) { rc.left = x ; rc.right = rc.left + uiLen - 1 ; rc.top = y - 1 ; rc.bottom = y ; fDark = ( uiFlags & DRAW3D_IN ) ? FALSE : TRUE ; } /* ok, it's gotta be left? */ else if ( uiFlags & DRAW3D_LEFTLINE ) { rc.left = x ; rc.right = x + 1 ; rc.top = y ; rc.bottom = y + uiLen ; fDark = ( uiFlags & DRAW3D_IN ) ? TRUE : FALSE ; } /* well maybe it's for the right side? */ else if ( uiFlags & DRAW3D_RIGHTLINE ) { rc.left = x - 1 ; rc.right = x ; rc.top = y ; rc.bottom = y + uiLen ; fDark = ( uiFlags & DRAW3D_IN ) ? FALSE : TRUE ; } /* bad drugs? */ else return ; /* select the appropriate color for the fill */ if ( fDark ) rgbOld = SetBkColor( hDC, GetNearestColor( hDC, tdGetShadowColor( GetBkColor( hDC ) ) ) ) ; else rgbOld = SetBkColor( hDC, GetNearestColor( hDC, tdGetHighlightColor( GetBkColor( hDC ) ) ) ) ; /* finally, draw the dern thing */ ExtTextOut( hDC, x, y, ETO_OPAQUE, &rc, NULL, 0, NULL ) ; SetBkColor( hDC, rgbOld ) ; } /* Draw3DLine1() */
VOID WINAPI tdDraw3DLine( HDC hDC, UINT x, UINT y, UINT uiLen, UINT uiShadowWidth, UINT uiFlags ) { HBRUSH hBrush ; BOOL fDark ; POINT Point[ 4 ] ; /* define a polgon with 4 points */ /* if width is zero, don't do nothin'! */ if ( !uiShadowWidth ) return ; /* if width is 1 use lines instead of polygons */ if (uiShadowWidth == 1) { Draw3DLine1( hDC, x, y, uiLen, uiFlags ) ; return ; } /* define shape of polygon--origin is always the same */ Point[0].x = x ; Point[0].y = y ; /* To do this we'll simply draw a polygon with four sides, using * the appropriate brush. I dare you to ask me why this isn't a * switch/case! */ if ( uiFlags & DRAW3D_TOPLINE ) { /* across to right */ Point[1].x = x + uiLen - (uiShadowWidth == 1 ? 1 : 0) ; Point[1].y = y ; /* down/left */ Point[2].x = x + uiLen - uiShadowWidth ; Point[2].y = y + uiShadowWidth ; /* accross to left */ Point[3].x = x + uiShadowWidth ; Point[3].y = y + uiShadowWidth ; /* select 'dark' brush if 'in'--'light' for 'out' */ fDark = ( uiFlags & DRAW3D_IN ) ? TRUE : FALSE ; } /* possibly the bottom? */ else if ( uiFlags & DRAW3D_BOTTOMLINE ) { /* across to right */ Point[1].x = x + uiLen ; Point[1].y = y ; /* up/left */ Point[2].x = x + uiLen - uiShadowWidth ; Point[2].y = y - uiShadowWidth ; /* accross to left */ Point[3].x = x + uiShadowWidth ; Point[3].y = y - uiShadowWidth ; /* select 'light' brush if 'in' */ fDark = ( uiFlags & DRAW3D_IN ) ? FALSE : TRUE ; } /* ok, it's gotta be left? */ else if ( uiFlags & DRAW3D_LEFTLINE ) { /* down */ Point[1].x = x ; Point[1].y = y + uiLen - (uiShadowWidth == 1 ? 1 : 0) ; /* up/right */ Point[2].x = x + uiShadowWidth ; Point[2].y = y + uiLen - uiShadowWidth ; /* down */ Point[3].x = x + uiShadowWidth ; Point[3].y = y + uiShadowWidth ; /* select 'dark' brush if 'in'--'light' for 'out' */ fDark = ( uiFlags & DRAW3D_IN ) ? TRUE : FALSE ; } /* well maybe it's for the right side? */ else if ( uiFlags & DRAW3D_RIGHTLINE ) { /* down */ Point[1].x = x ; Point[1].y = y + uiLen ; /* up/left */ Point[2].x = x - uiShadowWidth ; Point[2].y = y + uiLen - uiShadowWidth ; /* up */ Point[3].x = x - uiShadowWidth ; Point[3].y = y + uiShadowWidth ; /* select 'light' brush if 'in' */ fDark = ( uiFlags & DRAW3D_IN ) ? FALSE : TRUE ; } else return ; /* select NULL_PEN for no borders */ SelectObject( hDC, GetStockObject( NULL_PEN ) ) ; /* select the appropriate color for the fill */ hBrush = CreateSolidBrush( GetNearestColor( hDC, fDark ? tdGetShadowColor( GetBkColor( hDC ) ) : tdGetHighlightColor( GetBkColor( hDC ) ) ) ) ; hBrush = (HBRUSH)SelectObject( hDC, hBrush ) ; /* finally, draw the dern thing */ Polygon( hDC, (LPPOINT)Point, 4 ) ; /* restore what we killed */ hBrush = (HBRUSH)SelectObject( hDC, hBrush ) ; DeleteObject( hBrush ) ; } /*tdDraw3DLine() */
void PaintClc(HWND hwnd, struct ClcData *dat, HDC hdc, RECT * rcPaint) { HDC hdcMem; RECT clRect; int i, y, indent, index, fontHeight; struct ClcGroup *group; HBITMAP hBmpOsb, hOldBitmap; HFONT hOldFont; DWORD style = GetWindowLong(hwnd, GWL_STYLE); int status = GetGeneralisedStatus(); int grey = 0, groupCountsFontTopShift; HBRUSH hBrushAlternateGrey = NULL; // yes I know about GetSysColorBrush() COLORREF tmpbkcolour = style & CLS_CONTACTLIST ? (dat->useWindowsColours ? GetSysColor(COLOR_3DFACE) : dat->bkColour) : dat->bkColour; int minHeight = 16; for (i = 0; i < FONTID_LAST; i++) { if (minHeight < dat->fontInfo[i].fontHeight) { minHeight = dat->fontInfo[i].fontHeight; } } if (dat->rowHeight < minHeight) { dat->rowHeight = minHeight; } if (dat->greyoutFlags & pcli->pfnClcStatusToPf2(status) || style & WS_DISABLED) grey = 1; else if (GetFocus() != hwnd && dat->greyoutFlags & GREYF_UNFOCUS) grey = 1; GetClientRect(hwnd, &clRect); if (rcPaint == NULL) rcPaint = &clRect; if (IsRectEmpty(rcPaint)) return; y = -dat->yScroll; hdcMem = CreateCompatibleDC(hdc); hBmpOsb = CreateBitmap(clRect.right, clRect.bottom, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL); hOldBitmap = SelectObject(hdcMem, hBmpOsb); { TEXTMETRIC tm; hOldFont = SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPS].hFont); GetTextMetrics(hdcMem, &tm); groupCountsFontTopShift = tm.tmAscent; SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPCOUNTS].hFont); GetTextMetrics(hdcMem, &tm); groupCountsFontTopShift -= tm.tmAscent; } if (style & CLS_GREYALTERNATE) hBrushAlternateGrey = CreateSolidBrush(GetNearestColor(hdcMem, RGB(GetRValue(tmpbkcolour) - 10, GetGValue(tmpbkcolour) - 10, GetBValue(tmpbkcolour) - 10))); ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight); SetBkMode(hdcMem, TRANSPARENT); { HBRUSH hBrush; hBrush = CreateSolidBrush(tmpbkcolour); FillRect(hdcMem, rcPaint, hBrush); DeleteObject(hBrush); if (dat->hBmpBackground) { BITMAP bmp; HDC hdcBmp; int x, y; int maxx, maxy; int destw, desth; // XXX: Halftone isnt supported on 9x, however the scretch problems dont happen on 98. SetStretchBltMode(hdcMem, HALFTONE); GetObject(dat->hBmpBackground, sizeof(bmp), &bmp); hdcBmp = CreateCompatibleDC(hdcMem); SelectObject(hdcBmp, dat->hBmpBackground); y = dat->backgroundBmpUse & CLBF_SCROLL ? -dat->yScroll : 0; maxx = dat->backgroundBmpUse & CLBF_TILEH ? clRect.right : 1; maxy = dat->backgroundBmpUse & CLBF_TILEV ? maxy = rcPaint->bottom : y + 1; switch (dat->backgroundBmpUse & CLBM_TYPE) { case CLB_STRETCH: if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) { if (clRect.right * bmp.bmHeight < clRect.bottom * bmp.bmWidth) { desth = clRect.bottom; destw = desth * bmp.bmWidth / bmp.bmHeight; } else { destw = clRect.right; desth = destw * bmp.bmHeight / bmp.bmWidth; } } else { destw = clRect.right; desth = clRect.bottom; } break; case CLB_STRETCHH: if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) { destw = clRect.right; desth = destw * bmp.bmHeight / bmp.bmWidth; } else { destw = clRect.right; desth = bmp.bmHeight; } break; case CLB_STRETCHV: if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) { desth = clRect.bottom; destw = desth * bmp.bmWidth / bmp.bmHeight; } else { destw = bmp.bmWidth; desth = clRect.bottom; } break; default: //clb_topleft destw = bmp.bmWidth; desth = bmp.bmHeight; break; } for (; y < maxy; y += desth) { if (y < rcPaint->top - desth) continue; for (x = 0; x < maxx; x += destw) StretchBlt(hdcMem, x, y, destw, desth, hdcBmp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); } DeleteDC(hdcBmp); } } group = &dat->list; group->scanIndex = 0; indent = 0; for (index = 0; y < rcPaint->bottom;) { if (group->scanIndex == group->cl.count) { group = group->parent; indent--; if (group == NULL) break; group->scanIndex++; continue; } if (y > rcPaint->top - dat->rowHeight) { int iImage = -1; int selected = index == dat->selection && (dat->showSelAlways || dat->exStyle & CLS_EX_SHOWSELALWAYS || GetFocus() == hwnd) && group->cl.items[group->scanIndex]->type != CLCIT_DIVIDER; int hottrack = dat->exStyle & CLS_EX_TRACKSELECT && group->cl.items[group->scanIndex]->type != CLCIT_DIVIDER && dat->iHotTrack == index; SIZE textSize, countsSize, spaceSize; int width, checkboxWidth; char *szCounts; //alternating grey if (style & CLS_GREYALTERNATE && index & 1) { RECT rc; rc.top = y; rc.bottom = rc.top + dat->rowHeight; rc.left = 0; rc.right = clRect.right; FillRect(hdcMem, &rc, hBrushAlternateGrey); } //setup if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight); else if (group->cl.items[group->scanIndex]->type == CLCIT_INFO) { if (group->cl.items[group->scanIndex]->flags & CLCIIF_GROUPFONT) ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight); else ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight); } else if (group->cl.items[group->scanIndex]->type == CLCIT_DIVIDER) ChangeToFont(hdcMem, dat, FONTID_DIVIDERS, &fontHeight); else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags & CONTACTF_NOTONLIST) ChangeToFont(hdcMem, dat, FONTID_NOTONLIST, &fontHeight); else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && ((group->cl.items[group->scanIndex]->flags & CONTACTF_INVISTO && GetRealStatus(group->cl.items[group->scanIndex], status) != ID_STATUS_INVISIBLE) || (group->cl.items[group->scanIndex]->flags & CONTACTF_VISTO && GetRealStatus(group->cl.items[group->scanIndex], status) == ID_STATUS_INVISIBLE) ) ) { // the contact is in the always visible list and the proto is invisible // the contact is in the always invisible and the proto is in any other mode ChangeToFont(hdcMem, dat, group->cl.items[group->scanIndex]->flags & CONTACTF_ONLINE ? FONTID_INVIS : FONTID_OFFINVIS, &fontHeight); } else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && !(group->cl.items[group->scanIndex]->flags & CONTACTF_ONLINE)) ChangeToFont(hdcMem, dat, FONTID_OFFLINE, &fontHeight); else ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight); GetTextExtentPoint32(hdcMem, group->cl.items[group->scanIndex]->szText, lstrlen(group->cl.items[group->scanIndex]->szText), &textSize); width = textSize.cx; if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) { szCounts = pcli->pfnGetGroupCountsText(dat, group->cl.items[group->scanIndex]); if (szCounts[0]) { GetTextExtentPoint32A(hdcMem, " ", 1, &spaceSize); ChangeToFont(hdcMem, dat, FONTID_GROUPCOUNTS, &fontHeight); GetTextExtentPoint32A(hdcMem, szCounts, lstrlenA(szCounts), &countsSize); width += spaceSize.cx + countsSize.cx; } } if ((style & CLS_CHECKBOXES && group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) || (style & CLS_GROUPCHECKBOXES && group->cl.items[group->scanIndex]->type == CLCIT_GROUP) || (group->cl.items[group->scanIndex]->type == CLCIT_INFO && group->cl.items[group->scanIndex]->flags & CLCIIF_CHECKBOX)) checkboxWidth = dat->checkboxSize + 2; else checkboxWidth = 0; //background if (selected) { int x = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace - 2; ImageList_DrawEx(dat->himlHighlight, 0, hdcMem, x, y, min(width + 5, clRect.right - x), dat->rowHeight, CLR_NONE, CLR_NONE, dat->exStyle & CLS_EX_NOTRANSLUCENTSEL ? ILD_NORMAL : ILD_BLEND25); SetTextColor(hdcMem, dat->selTextColour); } else if (hottrack) SetHotTrackColour(hdcMem, dat); //checkboxes if (checkboxWidth) { RECT rc; HANDLE hTheme = NULL; // THEME if (IsWinVerXPPlus()) { if (!themeAPIHandle) { themeAPIHandle = GetModuleHandleA("uxtheme"); if (themeAPIHandle) { MyOpenThemeData = (HANDLE(WINAPI *) (HWND, LPCWSTR)) MGPROC("OpenThemeData"); MyCloseThemeData = (HRESULT(WINAPI *) (HANDLE)) MGPROC("CloseThemeData"); MyDrawThemeBackground = (HRESULT(WINAPI *) (HANDLE, HDC, int, int, const RECT *, const RECT *)) MGPROC("DrawThemeBackground"); } } // Make sure all of these methods are valid (i would hope either all or none work) if (MyOpenThemeData && MyCloseThemeData && MyDrawThemeBackground) { hTheme = MyOpenThemeData(hwnd, L"BUTTON"); } } rc.left = dat->leftMargin + indent * dat->groupIndent; rc.right = rc.left + dat->checkboxSize; rc.top = y + ((dat->rowHeight - dat->checkboxSize) >> 1); rc.bottom = rc.top + dat->checkboxSize; if (hTheme) { MyDrawThemeBackground(hTheme, hdcMem, BP_CHECKBOX, group->cl.items[group->scanIndex]->flags & CONTACTF_CHECKED ? (hottrack ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL) : (hottrack ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL), &rc, &rc); } else DrawFrameControl(hdcMem, &rc, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT | (group->cl.items[group->scanIndex]->flags & CONTACTF_CHECKED ? DFCS_CHECKED : 0) | (hottrack ? DFCS_HOT : 0)); if (hTheme && MyCloseThemeData) { MyCloseThemeData(hTheme); hTheme = NULL; } } //icon if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) iImage = group->cl.items[group->scanIndex]->group->expanded ? IMAGE_GROUPOPEN : IMAGE_GROUPSHUT; else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) iImage = group->cl.items[group->scanIndex]->iImage; if (iImage != -1) { /*COLORREF colourFg=dat->selBkColour; int mode=ILD_NORMAL; if(selected) mode=ILD_SELECTED; else if(hottrack) {mode=ILD_FOCUS; colourFg=dat->hotTextColour;} else if(group->cl.items[group->scanIndex]->type==CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags&CONTACTF_NOTONLIST) {colourFg=dat->fontInfo[FONTID_NOTONLIST].colour; mode=ILD_BLEND50;} ImageList_DrawEx(himlCListClc,iImage,hdcMem,dat->leftMargin+indent*dat->groupIndent+checkboxWidth,y+((dat->rowHeight-16)>>1),0,0,CLR_NONE,colourFg,mode); */ // this doesnt use CLS_CONTACTLIST since the colour prolly wont match anyway COLORREF colourFg = dat->selBkColour; int mode = ILD_NORMAL; if (hottrack) { colourFg = dat->hotTextColour; } else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags & CONTACTF_NOTONLIST) { colourFg = dat->fontInfo[FONTID_NOTONLIST].colour; mode = ILD_BLEND50; } if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && dat->showIdle && (group->cl.items[group->scanIndex]->flags & CONTACTF_IDLE) && GetRealStatus(group->cl.items[group->scanIndex], ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) mode = ILD_SELECTED; ImageList_DrawEx(himlCListClc, iImage, hdcMem, dat->leftMargin + indent * dat->groupIndent + checkboxWidth, y + ((dat->rowHeight - 16) >> 1), 0, 0, CLR_NONE, colourFg, mode); } //text if (group->cl.items[group->scanIndex]->type == CLCIT_DIVIDER) { RECT rc; rc.top = y + (dat->rowHeight >> 1); rc.bottom = rc.top + 2; rc.left = dat->leftMargin + indent * dat->groupIndent; rc.right = rc.left + ((clRect.right - rc.left - textSize.cx) >> 1) - 3; DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT); TextOut(hdcMem, rc.right + 3, y + ((dat->rowHeight - fontHeight) >> 1), group->cl.items[group->scanIndex]->szText, lstrlen(group->cl.items[group->scanIndex]->szText)); rc.left = rc.right + 6 + textSize.cx; rc.right = clRect.right; DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT); }
INT Test_NtUserSelectPalette(PTESTINFO pti) { HPALETTE hPal, hOldPal; HWND hWnd; HDC hDC, hCompDC; struct { LOGPALETTE logpal; PALETTEENTRY entry[20]; } pal; ZeroMemory(&pal, sizeof(pal)); pal.logpal.palVersion = 0x300; pal.logpal.palNumEntries = 6; pal.entry[0] = PALENTRY(0,0,0); pal.entry[1] = PALENTRY(255,255,255); pal.entry[2] = PALENTRY(128,128,128); pal.entry[3] = PALENTRY(128,0,0); pal.entry[4] = PALENTRY(0,128,0); pal.entry[5] = PALENTRY(0,0,128); hPal = CreatePalette(&pal.logpal); ASSERT(hPal); TEST(DeletePalette(hPal) == 1); hPal = CreatePalette(&pal.logpal); ASSERT(hPal); /* Create a window */ hWnd = CreateWindowW(L"BUTTON", L"TestWindow", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, g_hInstance, 0); hDC = GetDC(hWnd); ASSERT(hDC); hCompDC = CreateCompatibleDC(hDC); ASSERT(hCompDC); /* Test NULL DC */ SetLastError(ERROR_SUCCESS); hOldPal = NtUserSelectPalette(NULL, hPal, 0); TEST(hOldPal == 0); TEST(GetLastError() == ERROR_SUCCESS); /* Test invalid DC */ SetLastError(ERROR_SUCCESS); hOldPal = NtUserSelectPalette((HDC)-1, hPal, 0); TEST(hOldPal == 0); TEST(GetLastError() == ERROR_SUCCESS); /* Test NULL palette */ SetLastError(ERROR_SUCCESS); hOldPal = NtUserSelectPalette(hDC, NULL, 0); TEST(hOldPal == 0); TEST(GetLastError() == ERROR_SUCCESS); /* Test invalid palette */ SetLastError(ERROR_SUCCESS); hOldPal = NtUserSelectPalette(hDC, (HPALETTE)-1, 0); TEST(hOldPal == 0); TEST(GetLastError() == ERROR_SUCCESS); /* Test valid palette */ hOldPal = NtUserSelectPalette(hDC, hPal, 0); TEST(hOldPal != 0); TEST(hOldPal == GetStockObject(DEFAULT_PALETTE)); /* We cannot Delete the palette */ TEST(DeletePalette(hPal) == 0); /* We can still select the Palette into a compatible DC */ hOldPal = NtUserSelectPalette(hCompDC, hPal, 0); TEST(hOldPal != 0); #if 0 RealizePalette(hDC); GetClientRect(hWnd, &rect); FillRect(hDC, &rect, GetSysColorBrush(COLOR_BTNSHADOW)); TEST(GetNearestColor(hDC, RGB(0,0,0)) == RGB(0,0,0)); TEST(GetNearestColor(hDC, RGB(0,0,1)) == RGB(0,0,1)); ReleaseDC(hWnd, hDC); DestroyWindow(hWnd); RECT rect; HBITMAP hBmp; BITMAPINFOHEADER bmih = {sizeof(BITMAPINFOHEADER), // biSize 3, // biWidth 3, // biHeight 1, // biPlanes 8, // biBitCount BI_RGB, // biCompression 0, // biSizeImage 92, // biXPelsPerMeter 92, // biYPelsPerMeter 6, // biClrUsed 6}; // biClrImportant BYTE bits[3][3] = {{0,1,2},{3,4,5},{6,1,2}}; struct { BITMAPINFOHEADER bmih; RGBQUAD colors[6]; } bmi = {{sizeof(BITMAPINFOHEADER),3,3,1,8,BI_RGB,0,92,92,6,6}, {{0,0,0,0},{255,255,255,0},{255,0,0,0}, {0,255,0,0},{0,0,255,0},{128,128,128,0}}}; hBmp = CreateDIBitmap(hCompDC, &bmih, CBM_INIT, &bits, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); ASSERT(hBmp); SetLastError(0); TEST(NtGdiSelectBitmap(hCompDC, hBmp)); hOldPal = NtUserSelectPalette(hCompDC, hPal, 0); TEST(hOldPal != NULL); RealizePalette(hCompDC); TEST(GetNearestColor(hCompDC, RGB(0,0,0)) == RGB(0,0,0)); TEST(GetNearestColor(hCompDC, RGB(0,0,1)) == RGB(0,0,0)); TEST(GetNearestColor(hCompDC, RGB(100,0,0)) == RGB(0,0,0)); TEST(GetNearestColor(hCompDC, RGB(250,250,250)) == RGB(255,255,255)); TEST(GetNearestColor(hCompDC, RGB(120,100,110)) == RGB(128,128,128)); printf("nearest = 0x%x\n", GetNearestColor(hCompDC, RGB(120,100,110))); #endif return APISTATUS_NORMAL; }
static void copy_pixtemp(int id, int x, int y) { COLORREF cf; HDC hdc, hdcPix; HBITMAP xpixOld; HBRUSH hBrush, hOBrush; int x0, y0, x1, y1, x_abs, y_abs; if (!WI[id].pixcopymode) return; x -= tempx; y -= tempy; if (pixclamp) { x = max(clampx1, x); x = min(clampx2, x); y = max(clampy1, y); y = min(clampy2, y); } x0 = max(0, -x); x0 = min(x0, temp_dx); y0 = max(0, -y); y0 = min(y0, temp_dy); x1 = max(0, x); x1 = min(x1, temp_dx); y1 = max(0, y); y1 = min(y1, temp_dy); x_abs = abs(x); y_abs = abs(y); hdc = GetDC(WI[id].child[C_DRAWAREA].hwnd); hdcPix = CreateCompatibleDC(hdc); xpixOld = SelectObject(hdcPix, pixtemp); cf = GetNearestColor(hdc, RGB(127,127,127)); hBrush = CreateSolidBrush(cf); hOBrush = SelectObject(hdc, hBrush); if (x1) FillRectangle(tempx1, tempy1, x1, temp_dy, hdc, hBrush); if (y1) FillRectangle(tempx1, tempy1, temp_dx, y1, hdc, hBrush); if (x0) FillRectangle(tempx1 + (temp_dx - x_abs), tempy1, x0, temp_dy, hdc, hBrush); if (y0) FillRectangle(tempx1, tempy1 + (temp_dy - y_abs), temp_dx, y0, hdc, hBrush); SelectObject(hdc, hOBrush); DeleteObject(hBrush); BitBlt(hdc, tempx1 + x1, tempy1 + y1, temp_dx - x_abs, temp_dy - y_abs, hdcPix, x0, y0, SRCCOPY); SelectObject(hdcPix, xpixOld); DeleteDC(hdcPix); ReleaseDC(WI[id].child[C_DRAWAREA].hwnd, hdc); }
BOOL GdiSelectBrush(HDC32 hDC32, LPBRUSHINFO lpBrushInfo) { UINT uiCompatibility; BOOL bDither; COLORREF crColor,crTemp; LPIMAGEINFO lpImageInfo; HBITMAP hBitmap; int nDepth = 0; WORD wBrushType; int i; if (lpBrushInfo->lpBrush.lbColor & PALETTE_MASK) crColor = TWIN_PaletteRGB(hDC32, lpBrushInfo->lpBrush.lbColor); else crColor = lpBrushInfo->lpBrush.lbColor; if (lpBrushInfo->lpBrush.lbStyle == BS_SOLID) { wBrushType = LOWORD(lpBrushInfo->dwFlags); if (!(lpBrushInfo->dwFlags & DCX_DISPLAY_DC)) /* we have to re-realize solid brush, dither if needed */ wBrushType = BFP_UNASSIGNED; if (hDC32->hBitmap) { /* if the brush is realized, but its depth is different */ /* from the currently selected bitmap, it has to be re- */ /* realized */ lpImageInfo = GETBITMAPINFO(hDC32->hBitmap); nDepth = lpImageInfo->BitsPixel; if (nDepth != (int)LOBYTE(HIWORD(lpBrushInfo->dwFlags))) wBrushType = BFP_UNASSIGNED; RELEASEBITMAPINFO(lpImageInfo); } if (wBrushType == BFP_UNASSIGNED) { /* solid brush needs to be realized; */ /* gets resolved to either BFP_PIXEL (solid color) */ /* or BFP_PIXMAP (dithered pattern) */ if (nDepth == 1) { if ((crColor == RGB(0,0,0)) || crColor == RGB(255,255,255)) bDither = FALSE; else bDither = TRUE; } else { uiCompatibility = GetCompatibilityFlags(0); if (!(uiCompatibility & WD_NODITHERPURE)) { for (i = 0, bDither = TRUE; bDither && i < 16; i ++) if (RGB(VGAColors[i].rgbRed, VGAColors[i].rgbGreen, VGAColors[i].rgbBlue) == crColor) bDither = FALSE; } else { crTemp = GetNearestColor(GETHDC16(hDC32),crColor); if (lpBrushInfo->lpBrush.lbColor & PALETTE_RGB) { bDither = FALSE; crColor = crTemp; } else bDither = (crColor != crTemp); } } if (!bDither) { wBrushType = BFP_PIXEL; lpBrushInfo->lpPrivate = (LPVOID)DRVCALL_COLORS (PLH_MAKEPIXEL, crColor, 0L,0L); } else { hBitmap = GdiDitherColor (GETHDC16(hDC32),crColor,nDepth); lpBrushInfo->lpBrush.lbHatch = (int)hBitmap; wBrushType = BFP_PIXMAP; lpImageInfo = GETBITMAPINFO(hBitmap); if (!lpImageInfo) { return FALSE; } lpBrushInfo->lpPrivate = (LPVOID)DRVCALL_IMAGES (PIH_CREATEBRUSH, BFP_PIXMAP,0L, lpImageInfo->lpDrvData); RELEASEBITMAPINFO(lpImageInfo); } lpBrushInfo->dwFlags = DCX_DISPLAY_DC | wBrushType; lpBrushInfo->dwFlags |= (BYTE)nDepth << 16; } } if (!lpBrushInfo->fIsRealized) { LSDS_PARAMS argptr; argptr.lsde_validate.dwInvalidMask = 0; argptr.lsde.point = hDC32->ptBrushOrg; DRVCALL_GRAPHICS(PGH_SETBRUSHORG, (DWORD)hDC32->lpDrvData,0L, &argptr); lpBrushInfo->fIsRealized = TRUE; } return TRUE; }
LRESULT CALLBACK _export BalloonProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static DWORD lasttime; // ??? should be a property static POINT ttpos; RECT rect; POINT point; int x, y, width, height; SIZE size; LPSTR ptr; char text[256]; switch (message) { case WM_CREATE: { HFONT hfont = CreateFont(-11, 0, 0, 0, FW_NORMAL, FALSE, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_CHARACTER_PRECIS, PROOF_QUALITY, FF_DONTCARE, "MS Sans Serif"); SetProp(hwnd,MAKEINTRESOURCE(atomFont),hfont); break; } /* case */ case WM_DESTROY: { HFONT hfont = (HFONT)GetProp(hwnd,MAKEINTRESOURCE(atomFont)); if (hfont) DeleteObject(hfont); RemoveProp(hwnd,MAKEINTRESOURCE(atomAlignStyle)); RemoveProp(hwnd,MAKEINTRESOURCE(atomTailSize)); RemoveProp(hwnd,MAKEINTRESOURCE(atomTimeout)); RemoveProp(hwnd,MAKEINTRESOURCE(atomFont)); break; } /* case */ case WM_ERASEBKGND: return 0L; case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONUP: ShowWindow(hwnd, SW_HIDE); if (IsWindow(GetParent(hwnd))) PostMessage(GetParent(hwnd), BAN_VISIBLE, (WPARAM)hwnd, 0L); break; case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGED: return 0L; case WM_PAINT: { PAINTSTRUCT ps; COLORREF clrBackgr; HBRUSH hbrBackgr; HRGN hrgn; int AlignStyle=(int)GetProp(hwnd,MAKEINTRESOURCE(atomAlignStyle)); HFONT hfont = (HFONT)GetProp(hwnd,MAKEINTRESOURCE(atomFont)); HDC hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); clrBackgr=GetNearestColor(hdc, RGB(255,255,192)); hbrBackgr = CreateSolidBrush(clrBackgr); #if defined __WIN32__ hrgn=CreateRectRgn(0,0,1,1); GetWindowRgn(hwnd,hrgn); /* Win32-only */ #else #if BM_RADIUS==0 hrgn=CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom); #else hrgn=CreateRoundRectRgn(rect.left, rect.top, rect.right, rect.bottom, BM_RADIUS, BM_RADIUS); #endif #endif FillRgn(hdc,hrgn,hbrBackgr); FrameRgn(hdc,hrgn,GetStockObject(BLACK_BRUSH),1,1); DeleteObject(hbrBackgr); hfont = SelectObject(hdc, hfont); GetWindowText(hwnd, text, sizeof text); GetTextExtentPoint(hdc, text, lstrlen(text), &size); SetBkMode(hdc, TRANSPARENT); y=BM_MARGINTOP; if (AlignStyle==BAA_TOP) { int TailSize=(int)GetProp(hwnd,MAKEINTRESOURCE(atomTailSize)); y+=TailSize; } /* if */ for (ptr=strtok(text,"\n"); ptr!=NULL; ptr=strtok(NULL,"\n"), y+=size.cy) { GetTextExtentPoint(hdc, ptr, lstrlen(ptr), &size); x = ((rect.right-rect.left) - size.cx) / 2; TextOut(hdc, x, y, ptr, lstrlen(ptr)); } /* for */ SelectObject(hdc, hfont); EndPaint(hwnd, &ps); break; } /* case */ case WM_TIMER: { DWORD timeout=(DWORD)GetProp(hwnd,MAKEINTRESOURCE(atomTimeout)); DWORD curtime=GetTickCount(); GetCursorPos(&point); if (timeout==0) break; if (curtime >= lasttime+timeout) SendMessage(hwnd, BAM_SHOW, 0, 0L); break; } /* if */ case BAM_SETPOS: ttpos=*(LPPOINT)lParam; break; case BAM_SHOW: if (wParam) { HDC hdc; HRGN hrgn; int AlignStyle=(int)GetProp(hwnd,MAKEINTRESOURCE(atomAlignStyle)); int TailSize=(int)GetProp(hwnd,MAKEINTRESOURCE(atomTailSize)); HFONT hfont=(HFONT)GetProp(hwnd,MAKEINTRESOURCE(atomFont)); ASSERT(lParam!=0); lstrcpy(text, (LPSTR)lParam); SetWindowText(hwnd, text); InvalidateRect(hwnd, NULL, FALSE); hdc = GetDC(hwnd); hfont = SelectObject(hdc, hfont); for (ptr=strtok(text,"\n"), width=height=0; ptr!=NULL; ptr=strtok(NULL,"\n")) { GetTextExtentPoint(hdc, ptr, lstrlen(ptr), &size); width = max(width, size.cx); height += size.cy; } /* for */ SelectObject(hdc, hfont); ReleaseDC(hwnd, hdc); width += 2*BM_MARGINX; height += BM_MARGINTOP + BM_MARGINBOTTOM; #if 0 // round width up to multiple of 16 pixels and height up to a multiple // of 8 pixels width+=16-1; width=width - (width%16); height+=8-1; height=height - (height%8); #endif // also add the tail size to the height height+=TailSize; // check alignment switch (AlignStyle) { case BAA_TOP: x = ttpos.x - width/4; y = ttpos.y; break; case BAA_BOTTOM: x = ttpos.x - width/4; y = ttpos.y - height; break; } /* switch */ // check screen position against the screen size (width) if (x < 0) x = 0; else if (x+width >= GetSystemMetrics(SM_CXSCREEN)-1) x = GetSystemMetrics(SM_CXSCREEN) - width - 1; if (y < 0) y = 0; else if (y+height >= GetSystemMetrics(SM_CYSCREEN)-1) y = GetSystemMetrics(SM_CYSCREEN) - height - 1; GetWindowRect(hwnd,&rect); // get first, check later (for new region) SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, SWP_SHOWWINDOW|SWP_NOACTIVATE); hrgn=MakeBalloonRegion(width+1,height+1,BM_RADIUS,AlignStyle,TailSize,ttpos.x-x,ttpos.y-y); ASSERT(hrgn!=NULL); SetWindowRgn(hwnd, hrgn, TRUE); UpdateWindow(hwnd); lasttime=GetTickCount(); } else { ShowWindow(hwnd, SW_HIDE); lasttime=GetTickCount(); } /* if */ break; default: return DefWindowProc(hwnd, message, wParam, lParam); } /* switch */ return 0L; }
VOID CMimicsArcCtrl::DrawCtrl(HDC hDC, CONST RECT *pRect, BOOL bShape) { INT nPt; INT nPts; INT nMode; HPEN hOldPen; HPEN hBorderPen; POINT ptRadial[2]; double fxRadial; double fyRadial; HBRUSH hOldBrush; HBRUSH hInteriorBrush; HBITMAP hInteriorBitmap; LOGBRUSH sInteriorBrush; COLORREF nOldColor[2]; if ((hBorderPen = CreatePen(PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_MITER | m_nBorderStyle, m_nBorderSize, GetNearestColor(hDC, (!bShape) ? m_nBorderColor : VGA_COLOR_WHITE)))) { if ((hInteriorBitmap = LoadBitmap(GetModuleInstance(), (m_nInteriorHatch == HT_SOLID || m_nInteriorHatch < 0) ? MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHSOLID) : ((m_nInteriorHatch == HT_HORIZONTAL) ? MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHHORIZONTAL) : ((m_nInteriorHatch == HT_VERTICAL) ? MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHVERTICAL) : ((m_nInteriorHatch == HT_BDIAGONAL) ? MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHDIAGONALDOWN) : ((m_nInteriorHatch == HT_FDIAGONAL) ? MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHDIAGONALUP) : ((m_nInteriorHatch == HT_CROSS) ? MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHCROSS) : ((m_nInteriorHatch == HT_DIAGCROSS) ? MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHCROSSDIAGONAL) : ((m_nInteriorHatch == HT_LPOINTS) ? MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHPOINTSLOW) : ((m_nInteriorHatch == HT_MPOINTS) ? MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHPOINTSMEDIUM) : MAKEINTRESOURCE(IDB_MIMICSOBJECTCTLHATCHPOINTSHIGH)))))))))))) { sInteriorBrush.lbStyle = (m_nInteriorColor != (COLORREF)-1) ? ((m_nInteriorHatch > 0) ? BS_PATTERN : BS_SOLID) : BS_HOLLOW; sInteriorBrush.lbColor = (sInteriorBrush.lbStyle == BS_SOLID) ? GetNearestColor(hDC, (!bShape) ? m_nInteriorColor : VGA_COLOR_WHITE) : 0; sInteriorBrush.lbHatch = (sInteriorBrush.lbStyle == BS_PATTERN) ? (ULONG_PTR)hInteriorBitmap : (ULONG_PTR)NULL; if ((hInteriorBrush = CreateBrushIndirect(&sInteriorBrush)) != (HBRUSH)NULL) { if ((hOldPen = (HPEN)SelectObject(hDC, hBorderPen)) != (HPEN)NULL) { if ((hOldBrush = (HBRUSH)SelectObject(hDC, hInteriorBrush))) { for (nPt = 0, nPts = sizeof(ptRadial) / sizeof(POINT); nPt < nPts; nPt++) { fxRadial = (INT)((double)(pRect->left + pRect->right) / 2.0 + ((double)(pRect->right - pRect->left + pRect->bottom - pRect->top) / 2.0)*cos(2.0*M_PI - m_ptRadial[nPt])); fyRadial = (INT)((double)(pRect->top + pRect->bottom) / 2.0 + ((double)(pRect->right - pRect->left + pRect->bottom - pRect->top) / 2.0)*sin(2.0*M_PI - m_ptRadial[nPt])); ptRadial[nPt].x = (fxRadial >= 0.0) ? (INT)(fxRadial + 0.5) : (INT)(fxRadial - 0.5); ptRadial[nPt].y = (fyRadial >= 0.0) ? (INT)(fyRadial + 0.5) : (INT)(fyRadial - 0.5); } for (nMode = SetBkMode(hDC, OPAQUE), nOldColor[0] = SetBkColor(hDC, GetNearestColor(hDC, (!bShape) ? m_nInteriorColor : VGA_COLOR_WHITE)), nOldColor[1] = SetTextColor(hDC, GetNearestColor(hDC, (!bShape) ? m_nHatchColor : VGA_COLOR_WHITE)); m_nStyle & MIMICSARCCTRL_TYPE_ARC; ) { Arc(hDC, pRect->left + m_nBorderSize / 2, pRect->top + m_nBorderSize / 2, pRect->right - m_nBorderSize / 2 - m_nBorderSize % 2, pRect->bottom - m_nBorderSize / 2 - m_nBorderSize % 2, ptRadial[0].x, ptRadial[0].y, ptRadial[1].x, ptRadial[1].y); break; } for (; m_nStyle & MIMICSARCCTRL_TYPE_PIE; ) { Pie(hDC, pRect->left + m_nBorderSize / 2, pRect->top + m_nBorderSize / 2, pRect->right - m_nBorderSize / 2 - m_nBorderSize % 2, pRect->bottom - m_nBorderSize / 2 - m_nBorderSize % 2, ptRadial[0].x, ptRadial[0].y, ptRadial[1].x, ptRadial[1].y); break; } for (; m_nStyle & MIMICSARCCTRL_TYPE_CHORD; ) { Chord(hDC, pRect->left + m_nBorderSize / 2, pRect->top + m_nBorderSize / 2, pRect->right - m_nBorderSize / 2 - m_nBorderSize % 2, pRect->bottom - m_nBorderSize / 2 - m_nBorderSize % 2, ptRadial[0].x, ptRadial[0].y, ptRadial[1].x, ptRadial[1].y); break; } SetBkMode(hDC, nMode); SetBkColor(hDC, nOldColor[0]); SetTextColor(hDC, nOldColor[1]); SelectObject(hDC, hOldBrush); } SelectObject(hDC, hOldPen); } DeleteObject(hInteriorBrush); } DeleteObject(hInteriorBitmap); } DeletePen(hBorderPen); } }
/*********************************************************************** * CC_WMCommand16 [internal] */ static LRESULT CC_WMCommand16( HWND hDlg, WPARAM wParam, LPARAM lParam, WORD notifyCode, HWND hwndCtl ) { int r, g, b, i, xx; UINT cokmsg; HDC hdc; COLORREF *cr; LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER); TRACE("CC_WMCommand wParam=%lx lParam=%lx\n", wParam, lParam); switch (wParam) { case 0x2c2: /* edit notify RGB */ case 0x2c3: case 0x2c4: if (notifyCode == EN_UPDATE && !lpp->updating) { i = CC_CheckDigitsInEdit(hwndCtl, 255); r = GetRValue(lpp->lpcc->rgbResult); g = GetGValue(lpp->lpcc->rgbResult); b= GetBValue(lpp->lpcc->rgbResult); xx = 0; switch (wParam) { case 0x2c2: if ((xx = (i != r))) r = i; break; case 0x2c3: if ((xx = (i != g))) g = i; break; case 0x2c4: if ((xx = (i != b))) b = i; break; } if (xx) /* something has changed */ { lpp->lpcc->rgbResult = RGB(r, g, b); CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult); lpp->h = CC_RGBtoHSL('H', r, g, b); lpp->s = CC_RGBtoHSL('S', r, g, b); lpp->l = CC_RGBtoHSL('L', r, g, b); CC_EditSetHSL(hDlg, lpp->h, lpp->s, lpp->l); CC_PaintCross(hDlg, lpp->h, lpp->s); CC_PaintTriangle(hDlg, lpp->l); } } break; case 0x2bf: /* edit notify HSL */ case 0x2c0: case 0x2c1: if (notifyCode == EN_UPDATE && !lpp->updating) { i = CC_CheckDigitsInEdit(hwndCtl , wParam == 0x2bf ? 239:240); xx = 0; switch (wParam) { case 0x2bf: if ((xx = ( i != lpp->h))) lpp->h = i; break; case 0x2c0: if ((xx = ( i != lpp->s))) lpp->s = i; break; case 0x2c1: if ((xx = ( i != lpp->l))) lpp->l = i; break; } if (xx) /* something has changed */ { r = CC_HSLtoRGB('R', lpp->h, lpp->s, lpp->l); g = CC_HSLtoRGB('G', lpp->h, lpp->s, lpp->l); b = CC_HSLtoRGB('B', lpp->h, lpp->s, lpp->l); lpp->lpcc->rgbResult = RGB(r, g, b); CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult); CC_EditSetRGB(hDlg, lpp->lpcc->rgbResult); CC_PaintCross(hDlg, lpp->h, lpp->s); CC_PaintTriangle(hDlg, lpp->l); } } break; case 0x2cf: CC_SwitchToFullSize(hDlg, lpp->lpcc->rgbResult, &lpp->fullsize); SetFocus( GetDlgItem(hDlg, 0x2bf)); break; case 0x2c8: /* add colors ... column by column */ cr = lpp->lpcc->lpCustColors; cr[(lpp->nextuserdef % 2) * 8 + lpp->nextuserdef / 2] = lpp->lpcc->rgbResult; if (++lpp->nextuserdef == 16) lpp->nextuserdef = 0; CC_PaintUserColorArray(hDlg, 2, 8, lpp->lpcc->lpCustColors); break; case 0x2c9: /* resulting color */ hdc = GetDC(hDlg); lpp->lpcc->rgbResult = GetNearestColor(hdc, lpp->lpcc->rgbResult); ReleaseDC(hDlg, hdc); CC_EditSetRGB(hDlg, lpp->lpcc->rgbResult); CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult); r = GetRValue(lpp->lpcc->rgbResult); g = GetGValue(lpp->lpcc->rgbResult); b = GetBValue(lpp->lpcc->rgbResult); lpp->h = CC_RGBtoHSL('H', r, g, b); lpp->s = CC_RGBtoHSL('S', r, g, b); lpp->l = CC_RGBtoHSL('L', r, g, b); CC_EditSetHSL(hDlg, lpp->h, lpp->s, lpp->l); CC_PaintCross(hDlg, lpp->h, lpp->s); CC_PaintTriangle(hDlg, lpp->l); break; case 0x40e: /* Help! */ /* The Beatles, 1965 ;-) */ i = RegisterWindowMessageA(HELPMSGSTRINGA); if (lpp->lpcc16) { if (lpp->lpcc->hwndOwner) SendMessageA(lpp->lpcc->hwndOwner, i, 0, (LPARAM)lpp->lpcc16); if ( CC_HookCallChk(lpp->lpcc)) CallWindowProc16( (WNDPROC16) lpp->lpcc16->lpfnHook, HWND_16(hDlg), WM_COMMAND, psh15, (LPARAM)lpp->lpcc16); } break; case IDOK : cokmsg = RegisterWindowMessageA(COLOROKSTRINGA); if (lpp->lpcc16) { if (lpp->lpcc->hwndOwner) if (SendMessageA(lpp->lpcc->hwndOwner, cokmsg, 0, (LPARAM)lpp->lpcc16)) break; /* do NOT close */ } if (lpp->lpcc16) { BYTE *ptr = MapSL(lpp->lpcc16->lpCustColors); memcpy(ptr, lpp->lpcc->lpCustColors, sizeof(COLORREF)*16); lpp->lpcc16->rgbResult = lpp->lpcc->rgbResult; } EndDialog(hDlg, 1) ; return TRUE ; case IDCANCEL : EndDialog(hDlg, 0) ; return TRUE ; } return FALSE; }
WPI_MRESULT CALLBACK GUIWindowProc( HWND hwnd, WPI_MSG msg, WPI_PARAM1 wparam, WPI_PARAM2 lparam ) { gui_window *wnd; gui_window *root; WORD param; WPI_POINT currentpoint; gui_coord point; gui_coord size; WPI_MRESULT ret; WPI_MINMAXINFO _W386FAR *info; WPI_RECT rect; HWND parent; CREATESTRUCT FAR *lpcs; wmcreate_info _W386FAR *wmcreateinfo; gui_create_info *createinfo; bool use_defproc; unsigned control_id; HWND win; #ifndef __OS2_PM__ gui_key_state key_state; RECT rc; #endif root = NULL; ret = 0L; use_defproc = FALSE; if( msg == WM_CREATE ) { lpcs = ( CREATESTRUCT FAR * )MK_FP32( (void *)lparam ); wmcreateinfo = (wmcreate_info _W386FAR *)MK_FP32( _wpi_getcreateparms( lpcs ) ); if ( wmcreateinfo != NULL ) { wnd = wmcreateinfo->wnd; createinfo = wmcreateinfo->info; if( wnd->hwnd == NULLHANDLE ) { #ifdef __OS2_PM__ if( wnd->root_frame != NULLHANDLE && wnd->root == NULLHANDLE ) { wnd->root = hwnd; } else { wnd->hwnd = hwnd; } #else if( _wpi_getparent( hwnd ) == HWND_DESKTOP ) { wnd->root = hwnd; wnd->root_frame = hwnd; } else { wnd->hwnd = hwnd; wnd->hwnd_frame = hwnd; } #endif } DoSetWindowLong( hwnd, wnd ); } } wnd = GUIGetWindow( hwnd ); if( wnd == NULL ) { return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); } if( GUIMDIProcessMessage( wnd, hwnd, msg, wparam, lparam, &ret ) ) { return( ret ); } if( wnd->root == hwnd ) { /* message for root window */ switch( msg ) { case WM_CREATE : #ifdef __OS2_PM__ wnd->root_pinfo.normal_pres = _wpi_createos2normpres( GUIMainHInst, hwnd ); #endif _wpi_getclientrect( wnd->root_frame, &wnd->root_client ); if( CreateBackgroundWnd( wnd, createinfo ) ) { return( 0 ); } return( (WPI_MRESULT)WPI_ERROR_ON_CREATE ); break; case WM_DESTROY : wnd->flags |= DOING_DESTROY; GUICloseToolBar( wnd ); //ret = _wpi_defwindowproc( hwnd, msg, wparam, lparam ); //wnd->root = NULL; //wnd->root_frame = NULL; return( 0L ); } } else if( ( wnd->root != NULLHANDLE ) && ( hwnd == wnd->hwnd ) ) { /* message for container window */ switch( msg ) { case WM_SIZE : if( !_wpi_isiconic( _wpi_getframe( hwnd ) ) ) { size.x = _wpi_getwmsizex( wparam, lparam ); size.y = _wpi_getwmsizey( wparam, lparam ); GUIDoResize( wnd, hwnd, &size ); } return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); break; case WM_MOVE : return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); break; case WM_VSCROLL : case WM_HSCROLL : case WM_CLOSE : return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); break; } } switch( msg ) { case WM_CREATE : #ifdef __OS2_PM__ wnd->hwnd_pinfo.normal_pres = _wpi_createos2normpres( GUIMainHInst, hwnd ); #endif NumWindows++; // even if -1 is returned, window will get WM_DESTROY win = GUIGetParentFrameHWND( wnd ); if( ( wnd->root_frame != NULLHANDLE ) || ( createinfo->style & GUI_POPUP ) ) { if( !GUIAddToSystemMenu( wnd, win, 0, NULL, createinfo->style ) ) { return( (WPI_MRESULT)WPI_ERROR_ON_CREATE ); } } else { if( !GUIAddToSystemMenu( wnd, win, createinfo->num_menus, createinfo->menu, createinfo->style ) ) { return( (WPI_MRESULT)WPI_ERROR_ON_CREATE ); } } _wpi_getclientrect( hwnd, &wnd->hwnd_client ); GUISetRowCol( wnd, NULL ); if( ( hwnd == wnd->hwnd ) && ( wnd->root == NULLHANDLE ) ) { GUIMDINewWindow( hwnd ); } if( GUIEVENTWND( wnd, GUI_INIT_WINDOW, NULL ) ) { wnd->flags |= SENT_INIT; GUISetScroll( wnd ); /* initalize scroll ranges */ GUIBringToFront( wnd ); return( 0 ); } else { /* app decided not to create window */ return( (WPI_MRESULT)WPI_ERROR_ON_CREATE ); } break; #if defined(__NT__) || defined(WILLOWS) case WM_CTLCOLORBTN : case WM_CTLCOLORDLG : //case WM_CTLCOLORLISTBOX : case WM_CTLCOLORSTATIC : //case WM_CTLCOLOREDIT : ret = (WPI_MRESULT)GUICtl3dCtlColorEx( msg, wparam, lparam ); if( ret == (HBRUSH)NULL ) { SetBkColor( (HDC)wparam, GetNearestColor( (HDC)wparam, GUIGetBack( wnd, GUI_BACKGROUND ) ) ); ret = (WPI_MRESULT)wnd->bk_brush; } return( ret ); #elif !defined( __OS2_PM__ ) case WM_CTLCOLOR : switch( HIWORD( lparam ) ) { case CTLCOLOR_BTN : case CTLCOLOR_DLG : case CTLCOLOR_EDIT : case CTLCOLOR_LISTBOX : case CTLCOLOR_MSGBOX : case CTLCOLOR_STATIC : ret = (WPI_MRESULT)GUICtl3dCtlColorEx( msg, wparam, lparam ); if( ret == (HBRUSH)NULL ) { SetBkColor( (HDC)wparam, GetNearestColor( (HDC)wparam, GUIGetBack( wnd, GUI_BACKGROUND ) ) ); ret = (WPI_MRESULT)wnd->bk_brush; } break; } return( ret ); #endif #ifndef __OS2_PM__ case WM_INITMENUPOPUP : return( GUIProcessInitMenuPopup( wnd, hwnd, msg, wparam, lparam ) ); case WM_MENUSELECT : return( GUIProcessMenuSelect( wnd, hwnd, msg, wparam, lparam ) ); #endif case WM_GETMINMAXINFO : info = (WPI_MINMAXINFO _W386FAR *)MK_FP32( (void *)lparam ); ret = _wpi_defwindowproc( hwnd, msg, wparam, lparam ); if( wnd->root == NULLHANDLE ) { parent = _wpi_getparent( hwnd ); _wpi_getclientrect( parent, &rect ); _wpi_setmaxposition( *info, 0, 0 ); _wpi_setmaxtracksize( info, _wpi_getwidthrect( rect ), _wpi_getheightrect( rect ) ); } return( ret ); case WM_ERASEBKGND: #ifdef __OS2_PM__ //GUIInvalidatePaintHandles( wnd ); return( (WPI_MRESULT)TRUE ); #else if( !_wpi_isiconic( hwnd ) ) { GetClientRect( hwnd, &rc ); FillRect( (HDC)wparam, &rc, wnd->bk_brush ); } use_defproc = TRUE; break; #endif #if !defined(__OS2_PM__) && !defined(WILLOWS) case WM_PAINTICON : { HICON old; old = SET_HICON( wnd->hwnd, wnd->icon ); ret = _wpi_defwindowproc( hwnd, msg, wparam, lparam ); SET_HICON( wnd->hwnd, old ); return( ret ); } #endif case WM_PAINT: if( _wpi_isiconic( hwnd ) ) { return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); } else { GUIPaint( wnd, hwnd, FALSE ); } break; #ifndef __OS2_PM__ case WM_ACTIVATEAPP : root = GUIGetRootWindow(); ActivateNC( root, wparam ); if( GUICurrWnd != NULL ) { ActivateNC( GUICurrWnd, wparam ); } use_defproc = (bool)wparam; // I'm cheating and using 'use_defproc' // outside of its self-documented purpose if( root ) GUIEVENTWND( root, GUI_ACTIVATEAPP, &use_defproc ); use_defproc = TRUE; break; #if 0 // this repaints the nc client area when the window loses focus to // a window that is not a descendant of a GUI window case WM_KILLFOCUS : if( !GUIIsGUIChild( (HWND)wparam ) ) { ActivateNC( wnd, FALSE ); } break; #endif case WM_SETFOCUS : if( !_wpi_ismsgsetfocus( msg, lparam ) ) { return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); } if( !EditControlHasFocus ) { if( SetFocusToParent() ) { return( 0L ); } } break; #endif case WM_VSCROLL : case WM_HSCROLL : GUIProcessScrollMsg( wnd, msg, wparam, lparam ); return( 0L ); #ifdef __NT__ case WM_MOUSEWHEEL : { // Try to handle mousewheel messages... // Fake them into GUIProcessScrollMsg() // as "normal" vertical scroll messages. short gcWheelDelta; //wheel delta from roll WORD wKey; // The wnd I get is not the same as WM_VSCROLL : above gets... // Note to self: Fix it... // Seems like the main app window gets the message, rather than // the MDI clients... gcWheelDelta = HIWORD(wparam); wKey = LOWORD(wparam); // Scroll wheel upwards gives 120 // " " downward " -120 if( wnd != GUICurrWnd ) // Send to child window with focus wnd = GUICurrWnd; if( gcWheelDelta > 0 ) { // positive - scroll up if( wKey == MK_CONTROL || wKey == MK_SHIFT ) GUIProcessScrollMsg( wnd, WM_VSCROLL, SB_PAGEUP, 0L ); else GUIProcessScrollMsg( wnd, WM_VSCROLL, SB_LINEUP, 0L ); } else { // negative - scroll down if( wKey == MK_CONTROL || wKey == MK_SHIFT ) GUIProcessScrollMsg( wnd, WM_VSCROLL, SB_PAGEDOWN, 0L ); else GUIProcessScrollMsg( wnd, WM_VSCROLL, SB_LINEDOWN, 0L ); } // Inform GUI system we are done with scrolling for now. GUIProcessScrollMsg( wnd, WM_VSCROLL, SB_ENDSCROLL, 0 ); } return( 0L ); #endif case WM_MOVE : use_defproc = TRUE; if( wnd->flags & DOING_CLOSE ) { break; } if( !GUIParentHasFlags( wnd, IS_MINIMIZED ) ) { GUIEVENTWND( wnd, GUI_MOVE, NULL ); } use_defproc = TRUE; break; case WM_SIZE: use_defproc = TRUE; if( wnd->flags & DOING_CLOSE ) { break; } if( _wpi_isiconic( _wpi_getframe( hwnd ) ) ) { wnd->flags |= IS_MINIMIZED; if( wnd->style & GUI_CHANGEABLE_FONT ) { GUIEnableSysMenuItem( wnd, GUI_CHANGE_FONT, FALSE ); } GUIEVENTWND( wnd, GUI_ICONIFIED, NULL ); if( GUIMDI ) { GUIBringNewToFront( wnd ); } } else { wnd->flags &= ~IS_MINIMIZED; size.x = _wpi_getwmsizex( wparam, lparam ); size.y = _wpi_getwmsizey( wparam, lparam ); GUIDoResize( wnd, hwnd, &size ); if( wnd->flags & IS_ROOT ) { win = GUIGetParentFrameHWND( wnd ); if( !_wpi_isiconic( win ) ) { GUIMaximizeZoomedChildren( wnd ); } } } //Call back to tell about resizing so system tray can be used WndSizeChange( hwnd, wparam, lparam ); break; case WM_MOUSEMOVE: currentpoint.x = GET_WM_MOUSEMOVE_POSX( wparam, lparam ); currentpoint.y = GET_WM_MOUSEMOVE_POSY( wparam, lparam ); point.x = currentpoint.x; point.y = currentpoint.y; GUIScreenToScaleR( &point ); if( ( currentpoint.x != prevpoint.x ) || ( currentpoint.y != prevpoint.y ) ) { prevpoint.x = currentpoint.x; prevpoint.y = currentpoint.y; SendPointEvent( wparam, lparam, wnd, GUI_MOUSEMOVE, TRUE ); } break; #ifndef __OS2_PM__ case WM_NCLBUTTONDOWN : case WM_NCMBUTTONDOWN : case WM_NCRBUTTONDOWN : CheckDoFront( wnd ); use_defproc = TRUE; break; case WM_RBUTTONDOWN: _wpi_setcapture( hwnd ); CheckDoFront( wnd ); SendPointEvent( wparam, lparam, wnd, GUI_RBUTTONDOWN, TRUE ); break; #else case WM_RBUTTONDOWN : WPI_MAKEPOINT( wparam, lparam, currentpoint ); win = PM1632WinWindowFromPoint( hwnd, ¤tpoint, FALSE ); if( ( win != (HWND)NULL) && ( win != hwnd ) ) { control_id = _wpi_getdlgctrlid( win ); if( control_id != 0 ) { GUIEVENTWND( wnd, GUI_CONTROL_RCLICKED, &control_id ); } } else { _wpi_setcapture( hwnd ); CheckDoFront( wnd ); SendPointEvent( wparam, lparam, wnd, GUI_RBUTTONDOWN, TRUE ); } break; #endif case WM_LBUTTONDOWN: _wpi_setcapture( hwnd ); CheckDoFront( wnd ); SendPointEvent( wparam, lparam, wnd, GUI_LBUTTONDOWN, TRUE ); use_defproc = TRUE; break; case WM_LBUTTONUP: _wpi_releasecapture(); SendPointEvent( wparam, lparam, wnd, GUI_LBUTTONUP, TRUE ); use_defproc = TRUE; break; case WM_RBUTTONUP: _wpi_releasecapture(); SendPointEvent( wparam, lparam, wnd, GUI_RBUTTONUP, TRUE ); break; case WM_LBUTTONDBLCLK: CheckDoFront( wnd ); SendPointEvent( wparam, lparam, wnd, GUI_LBUTTONDBLCLK, TRUE ); break; case WM_RBUTTONDBLCLK: CheckDoFront( wnd ); SendPointEvent( wparam, lparam, wnd, GUI_RBUTTONDBLCLK, TRUE ); break; case WM_SYSCOMMAND: param = _wpi_getid( wparam ); switch( param ) { case SC_NEXTWINDOW : if( GUIMDI ) { NextWndToFront( hwnd ); return( 0L ); } default : if( ( param & 0xf000 ) == ( SC_NEXTWINDOW & 0xf000 ) ) { /* top value same for all SC_* values */ return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); } else { ProcessMenu( wnd, param ); } break; } break; #ifdef __OS2_PM__ case WM_CONTROL : GUIProcessControlNotification( SHORT1FROMMP(wparam), SHORT2FROMMP(wparam), wnd ); break; #else case WM_PARENTNOTIFY: if( ( LOWORD(wparam) == WM_RBUTTONDOWN ) || ( LOWORD(wparam) == WM_LBUTTONDOWN ) || ( LOWORD(wparam) == WM_MBUTTONDOWN ) ) { if( wnd->root == NULLHANDLE ) { CheckDoFront( wnd ); } } if( LOWORD(wparam) == WM_RBUTTONDOWN ) { WPI_MAKEPOINT( wparam, lparam, currentpoint ); MapWindowPoints( hwnd, (HWND)NULL, ¤tpoint, 1 ); win = _wpi_windowfrompoint( currentpoint ); control_id = _wpi_getdlgctrlid( win ); if( control_id != 0 ) { if( _wpi_getparent(win) == hwnd ) { GUIEVENTWND( wnd, GUI_CONTROL_RCLICKED, &control_id ); } } } break; case WM_ENDSESSION : { gui_end_session es; es.endsession = (bool)wparam; es.logoff = (bool)( lparam == 0x80000000L ); GUIEVENTWND( wnd, GUI_ENDSESSION, &es ); return( 0L ); } case WM_QUERYENDSESSION : { gui_end_session es; es.endsession = (bool)wparam; es.logoff = (bool)( lparam == 0x80000000L ); // ENDSESSION_LOGOFF if( !GUIEVENTWND( wnd, GUI_QUERYENDSESSION, &es ) ) { return( TRUE ); } return( 0L ); } #endif case WM_COMMAND: if( _wpi_ismenucommand( wparam, lparam ) || IsToolBarCommand( wnd, wparam, lparam ) ) { /* from menu or toolbar */ ProcessMenu( wnd, _wpi_getid( wparam ) ); //SetFocusToParent(); } else { GUIProcessControlMsg( wparam, lparam, wnd, NULL ); } use_defproc = TRUE; break; #ifndef __OS2_PM__ case WM_VKEYTOITEM : use_defproc = FALSE; ret = -1; GUIGetKeyState( &key_state.state ); if( ( GUIWindowsMapKey( wparam, lparam, &key_state.key ) ) ) { ret = GUIEVENTWND( wnd, GUI_KEYTOITEM, &key_state ); } break; #endif #ifdef __OS2_PM__ case WM_CHAR : case WM_TRANSLATEACCEL : #else case WM_MENUCHAR : case WM_SYSKEYDOWN : case WM_SYSKEYUP : case WM_KEYUP : case WM_KEYDOWN : #endif return( GUIProcesskey( hwnd, msg, wparam, lparam ) ); case WM_CLOSE : if( wnd->flags & DOING_CLOSE ) { return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); } else if( wnd->style & GUI_CLOSEABLE ) { if( GUIEVENTWND( wnd, GUI_CLOSE, NULL ) ) { wnd->flags |= DOING_CLOSE; if( wnd->flags & IS_ROOT ) { return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); } else { _wpi_destroywindow( wnd->hwnd_frame ); } } } return( 0L ); // Message to deal with tray icons (Win 95 and NT 4.0 ). case WM_TRAYCALLBACK : TrayCallBack( hwnd, wparam, lparam ); return( 0L ); case WM_DESTROY : wnd->flags |= DOING_DESTROY; NumWindows--; GUIEVENTWND( wnd, GUI_DESTROY, NULL ); //ret = _wpi_defwindowproc( hwnd, msg, wparam, lparam ); GUIDestroyAllChildren( wnd ); if( wnd->flags & IS_ROOT ) { GUIDestroyAllPopupsWithNoParent(); } GUIFreeWindowMemory( wnd, FALSE, FALSE ); if( NumWindows == 0 ) { _wpi_postquitmessage( 0 ); Posted = TRUE; } return( 0L ); default: use_defproc = TRUE; } if( use_defproc ) { return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) ); } else { return( ret ); } }