/******************************************************************************** Copyright (C) 2012 Hugh Bailey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ********************************************************************************/ #include "OBSApi.h" struct CCStruct { DWORD structSize; //size of this structure DWORD curColor; //current color stored BOOL bDisabled; //whether the control is disabled or not long cx,cy; //size of control DWORD custColors[16]; //custom colors in the colors dialog box }; void WINAPI DrawColorControl(HDC hDC, CCStruct *pCCData); LRESULT WINAPI ColorControlProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); static DWORD customColors[16] = {0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF}; void CCSetCustomColors(DWORD *colors) { memcpy(customColors, colors, sizeof(DWORD)*16); } void CCGetCustomColors(DWORD *colors) { memcpy(colors, customColors, sizeof(DWORD)*16); } LRESULT WINAPI ColorControlProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { CCStruct *pCCData; switch(message) { case WM_NCCREATE: { CREATESTRUCT *pCreateData = (CREATESTRUCT*)lParam; //add custom data to window pCCData = (CCStruct*)malloc(sizeof(CCStruct)); zero(pCCData, sizeof(CCStruct)); SetWindowLongPtr(hwnd, 0, (LONG_PTR)pCCData); pCCData->structSize = sizeof(CCStruct); pCCData->curColor = 0xFFFFFF; pCCData->bDisabled = ((pCreateData->style & WS_DISABLED) != 0); pCCData->cx = pCreateData->cx; pCCData->cy = pCreateData->cy; for(int i=0; i<16; i++) pCCData->custColors[i] = 0xC0C0C0; return TRUE; } case WM_DESTROY: { pCCData = (CCStruct*)GetWindowLongPtr(hwnd, 0); if(pCCData) free(pCCData); break; } case WM_PAINT: { pCCData = (CCStruct*)GetWindowLongPtr(hwnd, 0); PAINTSTRUCT ps; HDC hDC = BeginPaint(hwnd, &ps); DrawColorControl(hDC, pCCData); EndPaint(hwnd, &ps); break; } case WM_ENABLE: { pCCData = (CCStruct*)GetWindowLongPtr(hwnd, 0); pCCData->bDisabled = !wParam; //redraw control HDC hDC = GetDC(hwnd); DrawColorControl(hDC, pCCData); ReleaseDC(hwnd, hDC); break; } case WM_LBUTTONDBLCLK: { pCCData = (CCStruct*)GetWindowLongPtr(hwnd, 0); if(pCCData->bDisabled) break; CHOOSECOLOR chooserData; zero(&chooserData, sizeof(chooserData)); chooserData.lStructSize = sizeof(chooserData); chooserData.hwndOwner = GetParent(hwnd); chooserData.Flags = CC_RGBINIT | CC_FULLOPEN; chooserData.rgbResult = pCCData->curColor; chooserData.lpCustColors = customColors; if(ChooseColor(&chooserData)) { pCCData->curColor = chooserData.rgbResult; HDC hDC = GetDC(hwnd); DrawColorControl(hDC, pCCData); ReleaseDC(hwnd, hDC); HWND hwndParent = GetParent(hwnd); DWORD controlID = (DWORD)GetWindowLongPtr(hwnd, GWLP_ID); SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(controlID, CCN_CHANGED), (LPARAM)hwnd); } break; } default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } void WINAPI DrawColorControl(HDC hDC, CCStruct *pCCData) { HDC hdcTemp; HBITMAP hBmp, hbmpOld; HBRUSH hBrush; RECT rect; //Create temp draw data hdcTemp = CreateCompatibleDC(hDC); hBmp = CreateCompatibleBitmap(hDC, pCCData->cx, pCCData->cy); hbmpOld = (HBITMAP)SelectObject(hdcTemp, hBmp); //draw the outline hBrush = CreateSolidBrush(INVALID); rect.top = rect.left = 0; rect.right = pCCData->cx; rect.bottom = pCCData->cy; FillRect(hdcTemp, &rect, hBrush); DeleteObject(hBrush); //draw the color hBrush = CreateSolidBrush(pCCData->bDisabled ? 0x808080 : pCCData->curColor); rect.top = rect.left = 1; rect.right = pCCData->cx-1; rect.bottom = pCCData->cy-1; FillRect(hdcTemp, &rect, hBrush); DeleteObject(hBrush); //Copy drawn data back onto the main device context BitBlt(hDC, 0, 0, pCCData->cx, pCCData->cy, hdcTemp, 0, 0, SRCCOPY); //Delete temp draw data SelectObject(hdcTemp, hbmpOld); DeleteObject(hBmp); DeleteDC(hdcTemp); } void InitColorControl(HINSTANCE hInstance) { WNDCLASS wnd; wnd.cbClsExtra = 0; wnd.cbWndExtra = sizeof(LPVOID); wnd.hbrBackground = NULL; wnd.hCursor = LoadCursor(NULL, IDC_ARROW); wnd.hIcon = NULL; wnd.hInstance = hInstance; wnd.lpfnWndProc = ColorControlProc; wnd.lpszClassName = COLOR_CONTROL_CLASS; wnd.lpszMenuName = NULL; wnd.style = CS_PARENTDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; RegisterClass(&wnd); } DWORD CCGetColor(HWND hwnd) { if(!hwnd) return 0; CCStruct *pCCData = (CCStruct*)GetWindowLongPtr(hwnd, 0); DWORD color = REVERSE_COLOR(pCCData->curColor); //MAKERGB(RGB_B(pCCData->curColor), RGB_G(pCCData->curColor), RGB_R(pCCData->curColor)); return color | 0xFF000000; } void CCSetColor(HWND hwnd, DWORD color) { if(!hwnd) return; color &= 0xFFFFFF; color = REVERSE_COLOR(color); CCStruct *pCCData = (CCStruct*)GetWindowLongPtr(hwnd, 0); pCCData->curColor = color; HDC hDC = GetDC(hwnd); DrawColorControl(hDC, pCCData); ReleaseDC(hwnd, hDC); } void CCSetColor(HWND hwnd, const Color3 &color) { CCSetColor(hwnd, (DWORD)Vect_to_RGB(color)); }