comparison win/dw.c @ 634:c6a216c8174f

Support for setting transparent colour for bitmaps Support for checkable menu items Mouse support on render window Fix bubble text on buttons dw_window_set_text() works for group box dw_window_set_size() and dw_window_set_pos_size() to allow negative values Add dw_draw_polygon()
author mhessling@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 10 Apr 2009 10:25:26 +0000
parents 6e84e055d981
children 6cec85b90635
comparison
equal deleted inserted replaced
633:87db549e79bc 634:c6a216c8174f
65 COLORREF _foreground[THREAD_LIMIT]; 65 COLORREF _foreground[THREAD_LIMIT];
66 COLORREF _background[THREAD_LIMIT]; 66 COLORREF _background[THREAD_LIMIT];
67 HPEN _hPen[THREAD_LIMIT]; 67 HPEN _hPen[THREAD_LIMIT];
68 HBRUSH _hBrush[THREAD_LIMIT]; 68 HBRUSH _hBrush[THREAD_LIMIT];
69 char *_clipboard_contents[THREAD_LIMIT]; 69 char *_clipboard_contents[THREAD_LIMIT];
70 int _PointerOnWnd[THREAD_LIMIT];
70 71
71 BYTE _red[] = { 0x00, 0xbb, 0x00, 0xaa, 0x00, 0xbb, 0x00, 0xaa, 0x77, 72 BYTE _red[] = { 0x00, 0xbb, 0x00, 0xaa, 0x00, 0xbb, 0x00, 0xaa, 0x77,
72 0xff, 0x00, 0xee, 0x00, 0xff, 0x00, 0xff, 0xaa, 0x00 }; 73 0xff, 0x00, 0xee, 0x00, 0xff, 0x00, 0xff, 0xaa, 0x00 };
73 BYTE _green[] = { 0x00, 0x00, 0xbb, 0xaa, 0x00, 0x00, 0xbb, 0xaa, 0x77, 74 BYTE _green[] = { 0x00, 0x00, 0xbb, 0xaa, 0x00, 0x00, 0xbb, 0xaa, 0x77,
74 0x00, 0xff, 0xee, 0x00, 0x00, 0xee, 0xff, 0xaa, 0x00 }; 75 0x00, 0xff, 0xee, 0x00, 0x00, 0xee, 0xff, 0xaa, 0x00 };
75 BYTE _blue[] = { 0x00, 0x00, 0x00, 0x00, 0xcc, 0xbb, 0xbb, 0xaa, 0x77, 76 BYTE _blue[] = { 0x00, 0x00, 0x00, 0x00, 0xcc, 0xbb, 0xbb, 0xaa, 0x77,
76 0x00, 0x00, 0x00, 0xff, 0xff, 0xee, 0xff, 0xaa, 0x00}; 77 0x00, 0x00, 0x00, 0xff, 0xff, 0xee, 0xff, 0xaa, 0x00};
77 78
78 HBRUSH _colors[18]; 79 HBRUSH _colors[18];
79 80
81 static int screenx, screeny;
80 82
81 LRESULT CALLBACK _browserWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 83 LRESULT CALLBACK _browserWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
82 void _resize_notebook_page(HWND handle, int pageid); 84 void _resize_notebook_page(HWND handle, int pageid);
83 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y); 85 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
84 int _lookup_icon(HWND handle, HICON hicon, int type); 86 int _lookup_icon(HWND handle, HICON hicon, int type);
259 isnt = 0; 261 isnt = 0;
260 } 262 }
261 return isnt; 263 return isnt;
262 } 264 }
263 265
266 void DrawTransparentBitmap(HDC hdc, HDC hdcSrc, HBITMAP hBitmap, int xStart, int yStart, COLORREF cTransparentColor)
267 {
268 BITMAP bm;
269 COLORREF cColor;
270 HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
271 HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
272 HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
273 POINT ptSize;
274
275 #if 0
276 hdcTemp = CreateCompatibleDC(hdc);
277 SelectObject(hdcTemp, hBitmap); // Select the bitmap
278 #else
279 hdcTemp = hdcSrc;
280 #endif
281
282 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
283 ptSize.x = bm.bmWidth; // Get width of bitmap
284 ptSize.y = bm.bmHeight; // Get height of bitmap
285 DPtoLP(hdcTemp, &ptSize, 1); // Convert from device
286
287 // to logical points
288
289 // Create some DCs to hold temporary data.
290 hdcBack = CreateCompatibleDC(hdc);
291 hdcObject = CreateCompatibleDC(hdc);
292 hdcMem = CreateCompatibleDC(hdc);
293 hdcSave = CreateCompatibleDC(hdc);
294
295 // Create a bitmap for each DC. DCs are required for a number of
296 // GDI functions.
297
298 // Monochrome DC
299 bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
300
301 // Monochrome DC
302 bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
303
304 bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
305 bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
306
307 // Each DC must select a bitmap object to store pixel data.
308 bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack);
309 bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);
310 bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem);
311 bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave);
312
313 // Set proper mapping mode.
314 SetMapMode(hdcTemp, GetMapMode(hdc));
315
316 // Save the bitmap sent here, because it will be overwritten.
317 BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
318
319 // Set the background color of the source DC to the color.
320 // contained in the parts of the bitmap that should be transparent
321 cColor = SetBkColor(hdcTemp, cTransparentColor);
322
323 // Create the object mask for the bitmap by performing a BitBlt
324 // from the source bitmap to a monochrome bitmap.
325 BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
326
327 // Set the background color of the source DC back to the original
328 // color.
329 SetBkColor(hdcTemp, cColor);
330
331 // Create the inverse of the object mask.
332 BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY);
333
334 // Copy the background of the main DC to the destination.
335 BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY);
336
337 // Mask out the places where the bitmap will be placed.
338 BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
339
340 // Mask out the transparent colored pixels on the bitmap.
341 BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
342
343 // XOR the bitmap with the background on the destination DC.
344 BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
345
346 // Copy the destination to the screen.
347 BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0,
348 SRCCOPY);
349
350 // Place the original bitmap back into the bitmap sent here.
351 BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
352
353 // Delete the memory bitmaps.
354 DeleteObject(SelectObject(hdcBack, bmBackOld));
355 DeleteObject(SelectObject(hdcObject, bmObjectOld));
356 DeleteObject(SelectObject(hdcMem, bmMemOld));
357 DeleteObject(SelectObject(hdcSave, bmSaveOld));
358
359 // Delete the memory DCs.
360 DeleteDC(hdcMem);
361 DeleteDC(hdcBack);
362 DeleteDC(hdcObject);
363 DeleteDC(hdcSave);
364 DeleteDC(hdcTemp);
365 }
366
264 DWORD GetDllVersion(LPCTSTR lpszDllName) 367 DWORD GetDllVersion(LPCTSTR lpszDllName)
265 { 368 {
266 369
267 HINSTANCE hinstDll; 370 HINSTANCE hinstDll;
268 DWORD dwVersion = 0; 371 DWORD dwVersion = 0;
1301 if(thisbox->items[z].type == TYPEBOX) 1404 if(thisbox->items[z].type == TYPEBOX)
1302 { 1405 {
1303 Box *boxinfo = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA); 1406 Box *boxinfo = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
1304 1407
1305 if(boxinfo && boxinfo->grouphwnd) 1408 if(boxinfo && boxinfo->grouphwnd)
1409 {
1306 MoveWindow(boxinfo->grouphwnd, 0, 0, 1410 MoveWindow(boxinfo->grouphwnd, 0, 0,
1307 width + vectorx, height + vectory, FALSE); 1411 width + vectorx, height + vectory, FALSE);
1412 }
1308 1413
1309 } 1414 }
1310 } 1415 }
1311 1416
1312 /* Notebook dialog requires additional processing */ 1417 /* Notebook dialog requires additional processing */
1511 } 1616 }
1512 break; 1617 break;
1513 case WM_SIZE: 1618 case WM_SIZE:
1514 { 1619 {
1515 int (*sizefunc)(HWND, int, int, void *) = tmp->signalfunction; 1620 int (*sizefunc)(HWND, int, int, void *) = tmp->signalfunction;
1516
1517 if(hWnd == tmp->window) 1621 if(hWnd == tmp->window)
1518 { 1622 {
1519 result = sizefunc(tmp->window, LOWORD(mp2), HIWORD(mp2), tmp->data); 1623 result = sizefunc(tmp->window, LOWORD(mp2), HIWORD(mp2), tmp->data);
1520 tmp = NULL; 1624 tmp = NULL;
1521 } 1625 }
1651 { 1755 {
1652 PAINTSTRUCT ps; 1756 PAINTSTRUCT ps;
1653 DWExpose exp; 1757 DWExpose exp;
1654 int (*exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction; 1758 int (*exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction;
1655 1759
1656 if(hWnd == tmp->window) 1760 if ( hWnd == tmp->window )
1657 { 1761 {
1658 BeginPaint(hWnd, &ps); 1762 BeginPaint(hWnd, &ps);
1659 exp.x = ps.rcPaint.left; 1763 exp.x = ps.rcPaint.left;
1660 exp.y = ps.rcPaint.top; 1764 exp.y = ps.rcPaint.top;
1661 exp.width = ps.rcPaint.right - ps.rcPaint.left; 1765 exp.width = ps.rcPaint.right - ps.rcPaint.left;
1831 * Call the user supplied callback 1935 * Call the user supplied callback
1832 */ 1936 */
1833 result = clickfunc(tmp->window, tmp->data); 1937 result = clickfunc(tmp->window, tmp->data);
1834 tmp = NULL; 1938 tmp = NULL;
1835 } 1939 }
1836 } /* Make sure it's the right window, and the right ID */ 1940 } /* this fires for checkable menu items */
1837 else if (tmp->window < (HWND)65536 && command == tmp->window) 1941 else if ( tmp->window < (HWND)65536 && command == tmp->window && tmp->message != WM_TIMER )
1838 { 1942 {
1839 _dw_toggle_checkable_menu_item( popup ? popup : tmp->window, (int)tmp->data ); 1943 _dw_toggle_checkable_menu_item( popup ? popup : tmp->window, (int)tmp->data );
1840 result = clickfunc(popup ? popup : tmp->window, tmp->data); 1944 result = clickfunc(popup ? popup : tmp->window, tmp->data);
1841 tmp = NULL; 1945 tmp = NULL;
1842 } 1946 }
1844 break; 1948 break;
1845 case WM_HSCROLL: 1949 case WM_HSCROLL:
1846 case WM_VSCROLL: 1950 case WM_VSCROLL:
1847 { 1951 {
1848 char tmpbuf[100]; 1952 char tmpbuf[100];
1849 HWND handle = (HWND)mp2; 1953 HWND handle = (HWND)mp2;
1850 int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction; 1954 int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
1851 1955
1852 GetClassName(handle, tmpbuf, 99); 1956 GetClassName(handle, tmpbuf, 99);
1853 1957
1854 if (strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0) 1958 if (strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0)
1981 break; 2085 break;
1982 case WM_HSCROLL: 2086 case WM_HSCROLL:
1983 case WM_VSCROLL: 2087 case WM_VSCROLL:
1984 { 2088 {
1985 HWND handle = (HWND)mp2; 2089 HWND handle = (HWND)mp2;
2090 char tmpbuf[100];
1986 2091
1987 if(dw_window_get_data(handle, "_dw_scrollbar")) 2092 if(dw_window_get_data(handle, "_dw_scrollbar"))
1988 { 2093 {
1989 int value = _HandleScroller(handle, (int)HIWORD(mp1), (int)LOWORD(mp1)); 2094 int value = _HandleScroller(handle, (int)HIWORD(mp1), (int)LOWORD(mp1));
1990 2095
1991 if(value > -1) 2096 if(value > -1)
1992 dw_scrollbar_set_pos(handle, value); 2097 dw_scrollbar_set_pos(handle, value);
1993 } 2098 }
1994 } 2099 GetClassName( hWnd, tmpbuf, 99 );
2100 if ( strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1 ) == 0 )
2101 {
2102 int value = _HandleScroller(hWnd, (int)HIWORD(mp1), (int)LOWORD(mp1));
2103 } }
1995 break; 2104 break;
1996 case WM_GETMINMAXINFO: 2105 case WM_GETMINMAXINFO:
1997 { 2106 {
1998 MINMAXINFO *info = (MINMAXINFO *)mp2; 2107 MINMAXINFO *info = (MINMAXINFO *)mp2;
1999 info->ptMinTrackSize.x = 8; 2108 info->ptMinTrackSize.x = 8;
2094 break; 2203 break;
2095 } 2204 }
2096 if(result != -1) 2205 if(result != -1)
2097 return result; 2206 return result;
2098 else 2207 else
2208 {
2099 return DefWindowProc(hWnd, msg, mp1, mp2); 2209 return DefWindowProc(hWnd, msg, mp1, mp2);
2210 }
2100 } 2211 }
2101 2212
2102 VOID CALLBACK _TimerProc(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime) 2213 VOID CALLBACK _TimerProc(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime)
2103 { 2214 {
2104 _wndproc(hwnd, msg, (WPARAM)idEvent, 0); 2215 _wndproc(hwnd, msg, (WPARAM)idEvent, 0);
2202 return DefWindowProc(hWnd, msg, mp1, mp2); 2313 return DefWindowProc(hWnd, msg, mp1, mp2);
2203 } 2314 }
2204 2315
2205 BOOL CALLBACK _rendwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) 2316 BOOL CALLBACK _rendwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
2206 { 2317 {
2318 RECT wndRect;
2319 POINTS points;
2320 POINT point;
2321 int threadid = dw_thread_id();
2322
2323
2207 switch( msg ) 2324 switch( msg )
2208 { 2325 {
2209 case WM_LBUTTONDOWN: 2326 case WM_LBUTTONDOWN:
2210 case WM_MBUTTONDOWN: 2327 case WM_MBUTTONDOWN:
2211 case WM_RBUTTONDOWN: 2328 case WM_RBUTTONDOWN:
2212 SetFocus(hWnd); 2329 SetFocus(hWnd);
2213 _wndproc(hWnd, msg, mp1, mp2); 2330 _wndproc(hWnd, msg, mp1, mp2);
2214 break; 2331 break;
2332 case WM_MOUSEMOVE:
2333 if ( threadid < 0 || threadid >= THREAD_LIMIT )
2334 threadid = 0;
2335 /*
2336 * Set the mouse capture and focus on the renderbox
2337 * when the mouse moves into the window.
2338 */
2339 points = MAKEPOINTS(mp2); /* get the mouse point */
2340 point.x = points.x;
2341 point.y = points.y;
2342 SetCapture( hWnd ); /* Capture the mouse input */
2343
2344 GetWindowRect( hWnd, &wndRect );
2345 ClientToScreen( hWnd, &point );
2346
2347 if ( PtInRect( &wndRect, point ) )
2348 { // Test if the pointer is on the window
2349
2350 if ( _PointerOnWnd[threadid] == 0 )
2351 {
2352 SetFocus(hWnd);
2353 _PointerOnWnd[threadid] = 1;
2354 }
2355 }
2356 else
2357 {
2358 ReleaseCapture();
2359 _PointerOnWnd[threadid] = 0;
2360 }
2361 /* call our standard Windows procedure */
2362 _wndproc(hWnd, msg, mp1, mp2);
2363 break;
2215 case WM_LBUTTONUP: 2364 case WM_LBUTTONUP:
2216 case WM_MBUTTONUP: 2365 case WM_MBUTTONUP:
2217 case WM_RBUTTONUP: 2366 case WM_RBUTTONUP:
2218 case WM_MOUSEMOVE:
2219 case WM_PAINT: 2367 case WM_PAINT:
2220 case WM_SIZE: 2368 case WM_SIZE:
2221 case WM_COMMAND: 2369 case WM_COMMAND:
2222 case WM_CHAR: 2370 case WM_CHAR:
2223 case WM_KEYDOWN: 2371 case WM_KEYDOWN:
2987 3135
2988 BOOL CALLBACK _BtProc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2) 3136 BOOL CALLBACK _BtProc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2)
2989 { 3137 {
2990 BubbleButton *bubble; 3138 BubbleButton *bubble;
2991 static int bMouseOver = 0; 3139 static int bMouseOver = 0;
3140 static BubbleButton *this_bubble = NULL;
2992 POINT point; 3141 POINT point;
2993 RECT rect; 3142 RECT rect;
2994 WNDPROC pOldProc; 3143 WNDPROC pOldProc;
2995 3144
2996 bubble = (BubbleButton *)GetWindowLongPtr(hwnd, GWLP_USERDATA); 3145 bubble = (BubbleButton *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
2997 3146 if ( bubble != this_bubble )
2998 if(!bubble) 3147 {
3148 /*
3149 * If we missed the release capture, then if the bubble details
3150 * from this window are different from the last we must be in a
3151 * different button, so delete the last bubble text
3152 */
3153 bMouseOver = 0;
3154 this_bubble = bubble;
3155 if ( hwndBubble )
3156 {
3157 _free_window_memory(hwndBubble, 0);
3158 DestroyWindow(hwndBubble);
3159 hwndBubble = 0;
3160 }
3161 }
3162
3163 if ( !bubble )
2999 return DefWindowProc(hwnd, msg, mp1, mp2); 3164 return DefWindowProc(hwnd, msg, mp1, mp2);
3000 3165
3001 /* We must save a pointer to the old 3166 /* We must save a pointer to the old
3002 * window procedure because if a signal 3167 * window procedure because if a signal
3003 * handler attached here destroys this 3168 * handler attached here destroys this
3020 _wndproc(hwnd, msg, mp1, mp2); 3185 _wndproc(hwnd, msg, mp1, mp2);
3021 break; 3186 break;
3022 case WM_LBUTTONUP: 3187 case WM_LBUTTONUP:
3023 { 3188 {
3024 SignalHandler *tmp = Root; 3189 SignalHandler *tmp = Root;
3190 /*
3191 * If we have bubbletext displaying when we
3192 * release the mouse, get rid of the bubbletext window
3193 */
3194 if ( hwndBubble )
3195 {
3196 _free_window_memory(hwndBubble, 0);
3197 DestroyWindow(hwndBubble);
3198 hwndBubble = 0;
3199 }
3025 3200
3026 /* Find any callbacks for this function */ 3201 /* Find any callbacks for this function */
3027 while(tmp) 3202 while(tmp)
3028 { 3203 {
3029 if(tmp->message == WM_COMMAND) 3204 if(tmp->message == WM_COMMAND)
3093 break; 3268 break;
3094 case WM_MOUSEMOVE: 3269 case WM_MOUSEMOVE:
3095 GetCursorPos(&point); 3270 GetCursorPos(&point);
3096 GetWindowRect(hwnd, &rect); 3271 GetWindowRect(hwnd, &rect);
3097 3272
3098 if(PtInRect(&rect, point)) 3273 if ( PtInRect(&rect, point) )
3099 { 3274 {
3100 if(hwnd != GetCapture()) 3275 if ( hwnd != GetCapture() )
3101 { 3276 {
3102 SetCapture(hwnd); 3277 SetCapture(hwnd);
3103 } 3278 }
3104 if(!bMouseOver) 3279 if ( !bMouseOver )
3105 { 3280 {
3106 bMouseOver = 1; 3281 bMouseOver = 1;
3107 if(!*bubble->bubbletext) 3282 if(!*bubble->bubbletext)
3108 break; 3283 break;
3109 3284
3188 case WM_CAPTURECHANGED: 3363 case WM_CAPTURECHANGED:
3189 /* This message means we are losing the capture for some reason 3364 /* This message means we are losing the capture for some reason
3190 * Either because we intentionally lost it or another window 3365 * Either because we intentionally lost it or another window
3191 * stole it 3366 * stole it
3192 */ 3367 */
3193 if(bMouseOver && hwndBubble) 3368 if ( bMouseOver && hwndBubble )
3194 { 3369 {
3195 bMouseOver = 0; 3370 bMouseOver = 0;
3196 _free_window_memory(hwndBubble, 0); 3371 _free_window_memory(hwndBubble, 0);
3197 DestroyWindow(hwndBubble); 3372 DestroyWindow(hwndBubble);
3198 hwndBubble = 0; 3373 hwndBubble = 0;
3199 } 3374 }
3200 break; 3375 break;
3201 } 3376 }
3202 3377
3203 if(!pOldProc) 3378 if ( !pOldProc )
3204 return DefWindowProc(hwnd, msg, mp1, mp2); 3379 return DefWindowProc(hwnd, msg, mp1, mp2);
3205 return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2); 3380 return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2);
3206 } 3381 }
3207 3382
3208 /* This function recalculates a notebook page for example 3383 /* This function recalculates a notebook page for example
3262 { 3437 {
3263 *icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); 3438 *icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
3264 windowtype = BS_ICON; 3439 windowtype = BS_ICON;
3265 } 3440 }
3266 else if ( stricmp( file + len - 4, ".bmp" ) == 0 ) 3441 else if ( stricmp( file + len - 4, ".bmp" ) == 0 )
3442 {
3443 *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
3444 windowtype = BS_BITMAP;
3445 }
3446 else if ( stricmp( file + len - 4, ".png" ) == 0 )
3267 { 3447 {
3268 *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 3448 *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
3269 windowtype = BS_BITMAP; 3449 windowtype = BS_BITMAP;
3270 } 3450 }
3271 free(file); 3451 free(file);
3403 _foreground[z] = RGB(128,128,128); 3583 _foreground[z] = RGB(128,128,128);
3404 _background[z] = DW_RGB_TRANSPARENT; 3584 _background[z] = DW_RGB_TRANSPARENT;
3405 _hPen[z] = CreatePen(PS_SOLID, 1, _foreground[z]); 3585 _hPen[z] = CreatePen(PS_SOLID, 1, _foreground[z]);
3406 _hBrush[z] = CreateSolidBrush(_foreground[z]); 3586 _hBrush[z] = CreateSolidBrush(_foreground[z]);
3407 _clipboard_contents[z] = NULL; 3587 _clipboard_contents[z] = NULL;
3588 _PointerOnWnd[z] = 0;
3408 } 3589 }
3409 3590
3410 if ( !IS_WINNTOR95 ) 3591 if ( !IS_WINNTOR95 )
3411 { 3592 {
3412 /* Get function pointers for the Win2k/98 menu functions */ 3593 /* Get function pointers for the Win2k/98 menu functions */
3427 */ 3608 */
3428 if ( (fname = getenv( "DWINDOWS_DEBUGFILE" ) ) != NULL ) 3609 if ( (fname = getenv( "DWINDOWS_DEBUGFILE" ) ) != NULL )
3429 { 3610 {
3430 dbgfp = fopen( fname, "w" ); 3611 dbgfp = fopen( fname, "w" );
3431 } 3612 }
3613 /*
3614 * Get screen size. Used to make calls to dw_screen_width()
3615 * and dw_screen-height() quicker, but to alos limit the
3616 * default size of windows.
3617 */
3618 screenx = GetSystemMetrics(SM_CXSCREEN);
3619 screeny = GetSystemMetrics(SM_CYSCREEN);
3432 return 0; 3620 return 0;
3433 } 3621 }
3434 3622
3435 /* 3623 /*
3436 * Runs a message loop for Dynamic Windows. 3624 * Runs a message loop for Dynamic Windows.
3863 * back: Background color in RGB format. 4051 * back: Background color in RGB format.
3864 */ 4052 */
3865 int API dw_window_set_color(HWND handle, ULONG fore, ULONG back) 4053 int API dw_window_set_color(HWND handle, ULONG fore, ULONG back)
3866 { 4054 {
3867 ColorInfo *cinfo; 4055 ColorInfo *cinfo;
4056 Box *newbox;
3868 char tmpbuf[100]; 4057 char tmpbuf[100];
3869 4058
3870 cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA); 4059 cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
4060 newbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
3871 4061
3872 GetClassName(handle, tmpbuf, 99); 4062 GetClassName(handle, tmpbuf, 99);
3873 4063
3874 if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW))==0) 4064 if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW))==0)
3875 { 4065 {
4027 newbox->cinfo.fore = newbox->cinfo.back = -1; 4217 newbox->cinfo.fore = newbox->cinfo.back = -1;
4028 4218
4029 hwndframe = CreateWindow(FRAMECLASSNAME, 4219 hwndframe = CreateWindow(FRAMECLASSNAME,
4030 "", 4220 "",
4031 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN, 4221 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
4222 0,0,2000,1000,
4223 DW_HWND_OBJECT,
4224 NULL,
4225 DWInstance,
4226 NULL);
4227
4228 newbox->cinfo.pOldProc = SubclassWindow(hwndframe, _colorwndproc);
4229 newbox->cinfo.fore = newbox->cinfo.back = -1;
4230
4231 SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
4232 return hwndframe;
4233 }
4234
4235 /*
4236 * INCOMPLETE
4237 * Create a new scroll Box to be packed.
4238 * Parameters:
4239 * type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
4240 * pad: Number of pixels to pad around the box.
4241 */
4242 HWND API dw_scrollbox_new(int type, int pad)
4243 {
4244 Box *newbox = calloc(sizeof(Box), 1);
4245 HWND hwndframe;
4246
4247 newbox->pad = pad;
4248 newbox->type = type;
4249 newbox->count = 0;
4250 newbox->grouphwnd = (HWND)NULL;
4251 newbox->cinfo.fore = newbox->cinfo.back = -1;
4252
4253 hwndframe = CreateWindow(FRAMECLASSNAME,
4254 "",
4255 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
4032 0,0,2000,1000, 4256 0,0,2000,1000,
4033 DW_HWND_OBJECT, 4257 DW_HWND_OBJECT,
4034 NULL, 4258 NULL,
4035 DWInstance, 4259 DWInstance,
4036 NULL); 4260 NULL);
4455 */ 4679 */
4456 dw_window_set_data( DW_HWND_OBJECT, buffer1, (void *)check ); 4680 dw_window_set_data( DW_HWND_OBJECT, buffer1, (void *)check );
4457 dw_window_set_data( DW_HWND_OBJECT, buffer2, (void *)disabled ); 4681 dw_window_set_data( DW_HWND_OBJECT, buffer2, (void *)disabled );
4458 } 4682 }
4459 4683
4460 #if 0 4684 /*
4461 /* 4685 * INCOMPLETE
4462 * TBD
4463 * Deletes the menu item specified 4686 * Deletes the menu item specified
4464 * Parameters: 4687 * Parameters:
4465 * menu: The handle to the menu in which the item was appended. 4688 * menu: The handle to the menu in which the item was appended.
4466 * id: Menuitem id. 4689 * id: Menuitem id.
4467 */ 4690 */
4468 void API dw_menu_delete_item(HMENUI menux, unsigned long id) 4691 void API dw_menu_delete_item(HMENUI menux, unsigned long id)
4469 { 4692 {
4470 HMENU mymenu = (HMENU)menux; 4693 HMENU mymenu = (HMENU)menux;
4471 4694
4472 if(IsWindow(menux) && !IsMenu(mymenu)) 4695 if ( IsWindow(menux) && !IsMenu(mymenu) )
4473 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu"); 4696 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu");
4474 4697
4475 DeleteMenu(mymenu, id, MF_BYCOMMAND); 4698 if ( DeleteMenu(mymenu, id, MF_BYCOMMAND) == 0 )
4699 {
4700 char lasterror[257];
4701 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), lasterror, 256, NULL);
4702 fprintf(stderr, "Error deleting menu: %s", lasterror);
4703 }
4476 DrawMenuBar(menux); 4704 DrawMenuBar(menux);
4477 } 4705 }
4478 #endif
4479 4706
4480 /* 4707 /*
4481 * Pops up a context menu at given x and y coordinates. 4708 * Pops up a context menu at given x and y coordinates.
4482 * Parameters: 4709 * Parameters:
4483 * menu: The handle the the existing menu. 4710 * menu: The handle the the existing menu.
4853 5080
4854 SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble); 5081 SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
4855 5082
4856 if(icon) 5083 if(icon)
4857 { 5084 {
4858 SendMessage(tmp, BM_SETIMAGE, 5085 SendMessage(tmp, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) icon);
4859 (WPARAM) IMAGE_ICON,
4860 (LPARAM) icon);
4861 } 5086 }
4862 else if(hbitmap) 5087 else if(hbitmap)
4863 { 5088 {
4864 SendMessage(tmp, BM_SETIMAGE, 5089 SendMessage(tmp, BM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap);
4865 (WPARAM) IMAGE_BITMAP,
4866 (LPARAM) hbitmap);
4867 } 5090 }
4868 return tmp; 5091 return tmp;
4869 } 5092 }
4870 5093
4871 /* 5094 /*
4890 5113
4891 windowtype = _dw_get_image_handle(filename, &icon, &hbitmap); 5114 windowtype = _dw_get_image_handle(filename, &icon, &hbitmap);
4892 5115
4893 tmp = CreateWindow( BUTTONCLASSNAME, 5116 tmp = CreateWindow( BUTTONCLASSNAME,
4894 "", 5117 "",
4895 // label_text,
4896 // WS_CHILD | BS_OWNERDRAW | WS_CLIPCHILDREN | WS_VISIBLE,
4897 windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE, 5118 windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE,
4898 0,0,2000,1000, 5119 0,0,2000,1000,
4899 DW_HWND_OBJECT, 5120 DW_HWND_OBJECT,
4900 (HMENU)id, 5121 (HMENU)id,
4901 DWInstance, 5122 DWInstance,
4985 5206
4986 SetWindowLongPtr( tmp, GWLP_USERDATA, (LONG_PTR)bubble ); 5207 SetWindowLongPtr( tmp, GWLP_USERDATA, (LONG_PTR)bubble );
4987 5208
4988 if ( icon ) 5209 if ( icon )
4989 { 5210 {
4990 SendMessage( tmp, BM_SETIMAGE, 5211 SendMessage( tmp, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) icon);
4991 (WPARAM) IMAGE_ICON,
4992 (LPARAM) icon);
4993 } 5212 }
4994 else if( hbitmap ) 5213 else if( hbitmap )
4995 { 5214 {
4996 SendMessage( tmp, BM_SETIMAGE, 5215 SendMessage( tmp, BM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap);
4997 (WPARAM) IMAGE_BITMAP,
4998 (LPARAM) hbitmap);
4999 } 5216 }
5000 return tmp; 5217 return tmp;
5001 } 5218 }
5002 5219
5003 /* 5220 /*
5365 * handle: Handle to the window. 5582 * handle: Handle to the window.
5366 * text: The text associsated with a given window. 5583 * text: The text associsated with a given window.
5367 */ 5584 */
5368 void API dw_window_set_text(HWND handle, char *text) 5585 void API dw_window_set_text(HWND handle, char *text)
5369 { 5586 {
5587 Box *thisbox;
5370 char tmpbuf[100]; 5588 char tmpbuf[100];
5371 5589
5372 GetClassName(handle, tmpbuf, 99); 5590 GetClassName(handle, tmpbuf, 99);
5373 5591
5374 SetWindowText(handle, text); 5592 SetWindowText(handle, text);
5375 5593
5376 /* Combobox */ 5594 /* Combobox */
5377 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0) 5595 if ( strnicmp( tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1) == 0 )
5378 SendMessage(handle, CB_SETEDITSEL, 0, MAKELPARAM(-1, 0)); 5596 SendMessage(handle, CB_SETEDITSEL, 0, MAKELPARAM(-1, 0));
5597 else if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1) == 0 )
5598 {
5599 /* groupbox */
5600 thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA );
5601 if ( thisbox && thisbox->grouphwnd != (HWND)NULL )
5602 SetWindowText( thisbox->grouphwnd, text );
5603 }
5379 } 5604 }
5380 5605
5381 /* 5606 /*
5382 * Gets the text used for a given window. 5607 * Gets the text used for a given window.
5383 * Parameters: 5608 * Parameters:
5565 _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady); 5790 _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady);
5566 } 5791 }
5567 if ( width == 0 ) width = usedx; 5792 if ( width == 0 ) width = usedx;
5568 if ( height == 0 ) height = usedy; 5793 if ( height == 0 ) height = usedy;
5569 SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE); 5794 SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE);
5795 #if 0
5796 /* force a configure event */
5797 SendMessage( handle, WM_SIZE, 0, MAKELPARAM(usedx, usedy) );
5798 #endif
5570 } 5799 }
5571 5800
5572 /* 5801 /*
5573 * Returns the width of the screen. 5802 * Returns the width of the screen.
5574 */ 5803 */
5575 int API dw_screen_width(void) 5804 int API dw_screen_width(void)
5576 { 5805 {
5577 return GetSystemMetrics(SM_CXSCREEN); 5806 return screenx;
5578 } 5807 }
5579 5808
5580 /* 5809 /*
5581 * Returns the height of the screen. 5810 * Returns the height of the screen.
5582 */ 5811 */
5583 int API dw_screen_height(void) 5812 int API dw_screen_height(void)
5584 { 5813 {
5585 return GetSystemMetrics(SM_CYSCREEN); 5814 return screeny;
5586 } 5815 }
5587 5816
5588 /* This should return the current color depth */ 5817 /* This should return the current color depth */
5589 unsigned long API dw_color_depth_get(void) 5818 unsigned long API dw_color_depth_get(void)
5590 { 5819 {
5604 * Parameters: 5833 * Parameters:
5605 * handle: Window (widget) handle. 5834 * handle: Window (widget) handle.
5606 * x: X location from the bottom left. 5835 * x: X location from the bottom left.
5607 * y: Y location from the bottom left. 5836 * y: Y location from the bottom left.
5608 */ 5837 */
5609 void API dw_window_set_pos(HWND handle, ULONG x, ULONG y) 5838 void API dw_window_set_pos(HWND handle, long x, long y)
5610 { 5839 {
5611 SetWindowPos(handle, (HWND)NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 5840 SetWindowPos(handle, (HWND)NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
5612 } 5841 }
5613 5842
5614 /* 5843 /*
5618 * x: X location from the bottom left. 5847 * x: X location from the bottom left.
5619 * y: Y location from the bottom left. 5848 * y: Y location from the bottom left.
5620 * width: Width of the widget. 5849 * width: Width of the widget.
5621 * height: Height of the widget. 5850 * height: Height of the widget.
5622 */ 5851 */
5623 void API dw_window_set_pos_size(HWND handle, ULONG x, ULONG y, ULONG width, ULONG height) 5852 void API dw_window_set_pos_size(HWND handle, long x, long y, ULONG width, ULONG height)
5624 { 5853 {
5625 int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0; 5854 int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
5626 Box *thisbox; 5855 Box *thisbox;
5627 /* 5856 /*
5628 * The following is an attempt to dynamically size a window based on the size of its 5857 * The following is an attempt to dynamically size a window based on the size of its
5633 if ( thisbox ) 5862 if ( thisbox )
5634 { 5863 {
5635 _resize_box(thisbox, &depth, 0, 0, &usedx, &usedy, 1, &usedpadx, &usedpady); 5864 _resize_box(thisbox, &depth, 0, 0, &usedx, &usedy, 1, &usedpadx, &usedpady);
5636 _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady); 5865 _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady);
5637 } 5866 }
5867 if ( width == 0 ) width = usedx;
5868 if ( height == 0 ) height = usedy;
5638 SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE); 5869 SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
5870 #if 0
5871 /* force a configure event */
5872 SendMessage( handle, WM_SIZE, 0, MAKELPARAM(width, height) );
5873 #endif
5639 } 5874 }
5640 5875
5641 /* 5876 /*
5642 * Gets the position and size of a given window (widget). 5877 * Gets the position and size of a given window (widget).
5643 * Parameters: 5878 * Parameters:
5645 * x: X location from the bottom left. 5880 * x: X location from the bottom left.
5646 * y: Y location from the bottom left. 5881 * y: Y location from the bottom left.
5647 * width: Width of the widget. 5882 * width: Width of the widget.
5648 * height: Height of the widget. 5883 * height: Height of the widget.
5649 */ 5884 */
5650 void API dw_window_get_pos_size(HWND handle, ULONG *x, ULONG *y, ULONG *width, ULONG *height) 5885 void API dw_window_get_pos_size(HWND handle, long *x, long *y, ULONG *width, ULONG *height)
5651 { 5886 {
5652 WINDOWPLACEMENT wp; 5887 WINDOWPLACEMENT wp;
5653 5888
5654 wp.length = sizeof(WINDOWPLACEMENT); 5889 wp.length = sizeof(WINDOWPLACEMENT);
5655 5890
5663 if(width) 5898 if(width)
5664 *width=dw_screen_width(); 5899 *width=dw_screen_width();
5665 if(height) 5900 if(height)
5666 *height=dw_screen_height(); 5901 *height=dw_screen_height();
5667 } 5902 }
5668 else 5903 else
5669 { 5904 {
5670 if(x) 5905 if(x)
5671 *x = wp.rcNormalPosition.left; 5906 *x = wp.rcNormalPosition.left;
5672 if(y) 5907 if(y)
5673 *y = wp.rcNormalPosition.top; 5908 *y = wp.rcNormalPosition.top;
7748 { 7983 {
7749 Box *newbox = calloc(sizeof(Box), 1); 7984 Box *newbox = calloc(sizeof(Box), 1);
7750 HWND tmp = CreateWindow(ObjectClassName, 7985 HWND tmp = CreateWindow(ObjectClassName,
7751 "", 7986 "",
7752 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN, 7987 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
7753 0,0,2000,1000, 7988 0,0,screenx,screeny,
7754 DW_HWND_OBJECT, 7989 DW_HWND_OBJECT,
7755 (HMENU)id, 7990 (HMENU)id,
7756 DWInstance, 7991 DWInstance,
7757 NULL); 7992 NULL);
7758 newbox->pad = 0; 7993 newbox->pad = 0;
7759 newbox->type = 0; 7994 newbox->type = 0;
7760 newbox->count = 0; 7995 newbox->count = 0;
7761 newbox->grouphwnd = (HWND)NULL; 7996 newbox->grouphwnd = (HWND)NULL;
7762 newbox->cinfo.pOldProc = SubclassWindow(tmp, _rendwndproc); 7997 newbox->cinfo.pOldProc = SubclassWindow(tmp, _rendwndproc);
7763 newbox->cinfo.fore = newbox->cinfo.back = -1; 7998 newbox->cinfo.fore = newbox->cinfo.back = -1;
7764 7999 SetWindowLongPtr( tmp, GWLP_USERDATA, (LONG_PTR)newbox );
7765 SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)newbox);
7766 return tmp; 8000 return tmp;
7767 } 8001 }
7768 8002
7769 /* Sets the current foreground drawing color. 8003 /* Sets the current foreground drawing color.
7770 * Parameters: 8004 * Parameters:
7899 SetPixel(hdcPaint, x2, y2, _foreground[threadid]); 8133 SetPixel(hdcPaint, x2, y2, _foreground[threadid]);
7900 if(!pixmap) 8134 if(!pixmap)
7901 ReleaseDC(handle, hdcPaint); 8135 ReleaseDC(handle, hdcPaint);
7902 } 8136 }
7903 8137
8138 /* Draw a closed polygon on a window (preferably a render window).
8139 * Parameters:
8140 * handle: Handle to the window.
8141 * pixmap: Handle to the pixmap. (choose only one of these)
8142 * fill: if true filled
8143 * number of points
8144 * x[]: X coordinates.
8145 * y[]: Y coordinates.
8146 */
8147 void API dw_draw_polygon(HWND handle, HPIXMAP pixmap, int fill, int npoints, int *x, int *y)
8148 {
8149 HDC hdcPaint;
8150 HBRUSH oldBrush;
8151 HPEN oldPen;
8152 POINT *points;
8153 int i;
8154 int threadid = dw_thread_id();
8155
8156 if(threadid < 0 || threadid >= THREAD_LIMIT)
8157 threadid = 0;
8158
8159 if ( handle )
8160 hdcPaint = GetDC( handle );
8161 else if ( pixmap )
8162 hdcPaint = pixmap->hdc;
8163 else
8164 return;
8165 if ( npoints )
8166 {
8167 /*
8168 * Allocate enough space for the number of points supplied plus 1.
8169 * Under windows, unless the first and last points are the same
8170 * the polygon won't be closed
8171 */
8172 points = (POINT *)malloc( (npoints+1) * sizeof(POINT) );
8173 /*
8174 * should check for NULL pointer return!
8175 */
8176 for ( i = 0 ; i < npoints ; i++ )
8177 {
8178 points[i].x = x[i];
8179 points[i].y = y[i];
8180 }
8181 if ( !( points[0].x == points[npoints-1].x
8182 && points[0].y == points[npoints-1].y ) )
8183 {
8184 /* set the last point to be the same as the first point... */
8185 points[npoints].x = points[0].x;
8186 points[npoints].y = points[0].y;
8187 /* ... and increment the number of points */
8188 npoints++;
8189 }
8190 }
8191
8192 oldBrush = SelectObject( hdcPaint, _hBrush[threadid] );
8193 oldPen = SelectObject( hdcPaint, _hPen[threadid] );
8194 if ( fill )
8195 Polygon( hdcPaint, points, npoints );
8196 else
8197 Polyline( hdcPaint, points, npoints );
8198 SelectObject( hdcPaint, oldBrush );
8199 SelectObject( hdcPaint, oldPen );
8200 if ( !pixmap )
8201 ReleaseDC( handle, hdcPaint );
8202 free(points);
8203 }
8204
7904 /* Draw a rectangle on a window (preferably a render window). 8205 /* Draw a rectangle on a window (preferably a render window).
7905 * Parameters: 8206 * Parameters:
7906 * handle: Handle to the window. 8207 * handle: Handle to the window.
7907 * pixmap: Handle to the pixmap. (choose only one of these) 8208 * pixmap: Handle to the pixmap. (choose only one of these)
7908 * x: X coordinate. 8209 * x: X coordinate.
8063 */ 8364 */
8064 HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth) 8365 HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth)
8065 { 8366 {
8066 HPIXMAP pixmap; 8367 HPIXMAP pixmap;
8067 HDC hdc; 8368 HDC hdc;
8369 COLORREF bkcolor;
8370 ULONG cx, cy;
8068 8371
8069 if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) 8372 if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
8070 return NULL; 8373 return NULL;
8071 8374
8072 hdc = GetDC(handle); 8375 hdc = GetDC(handle);
8074 pixmap->width = width; pixmap->height = height; 8377 pixmap->width = width; pixmap->height = height;
8075 8378
8076 pixmap->handle = handle; 8379 pixmap->handle = handle;
8077 pixmap->hbm = CreateCompatibleBitmap(hdc, width, height); 8380 pixmap->hbm = CreateCompatibleBitmap(hdc, width, height);
8078 pixmap->hdc = CreateCompatibleDC(hdc); 8381 pixmap->hdc = CreateCompatibleDC(hdc);
8382 pixmap->transcolor = DW_RGB_TRANSPARENT;
8079 8383
8080 SelectObject(pixmap->hdc, pixmap->hbm); 8384 SelectObject(pixmap->hdc, pixmap->hbm);
8081 8385
8082 ReleaseDC(handle, hdc); 8386 ReleaseDC(handle, hdc);
8387
8388 #if 0
8389 /* force a CONFIGURE event on the underlying renderbox */
8390 dw_window_get_pos_size( handle, NULL, NULL, &cx, &cy );
8391 SendMessage( handle, WM_SIZE, 0, MAKELPARAM(cx, cy) );
8392 #endif
8083 8393
8084 return pixmap; 8394 return pixmap;
8085 } 8395 }
8086 8396
8087 /* 8397 /*
8097 HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename) 8407 HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename)
8098 { 8408 {
8099 HPIXMAP pixmap; 8409 HPIXMAP pixmap;
8100 BITMAP bm; 8410 BITMAP bm;
8101 HDC hdc; 8411 HDC hdc;
8412 ULONG cx, cy;
8102 char *file = malloc(strlen(filename) + 5); 8413 char *file = malloc(strlen(filename) + 5);
8103 8414
8104 if (!file || !(pixmap = calloc(1,sizeof(struct _hpixmap)))) 8415 if (!file || !(pixmap = calloc(1,sizeof(struct _hpixmap))))
8105 { 8416 {
8106 if(file) 8417 if(file)
8126 hdc = GetDC(handle); 8437 hdc = GetDC(handle);
8127 8438
8128 pixmap->handle = handle; 8439 pixmap->handle = handle;
8129 pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 8440 pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
8130 8441
8131 if(!pixmap->hbm) 8442 if ( !pixmap->hbm )
8132 { 8443 {
8133 free(file); 8444 free(file);
8134 free(pixmap); 8445 free(pixmap);
8135 ReleaseDC(handle, hdc); 8446 ReleaseDC(handle, hdc);
8136 return NULL; 8447 return NULL;
8137 } 8448 }
8138 8449
8139 pixmap->hdc = CreateCompatibleDC(hdc); 8450 pixmap->hdc = CreateCompatibleDC( hdc );
8140 8451 GetObject( pixmap->hbm, sizeof(bm), &bm );
8141 GetObject(pixmap->hbm, sizeof(bm), &bm);
8142
8143 pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight; 8452 pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight;
8144 8453 SelectObject( pixmap->hdc, pixmap->hbm );
8145 SelectObject(pixmap->hdc, pixmap->hbm); 8454 ReleaseDC( handle, hdc );
8146 8455 free( file );
8147 ReleaseDC(handle, hdc); 8456 pixmap->transcolor = DW_RGB_TRANSPARENT;
8148 8457
8149 free(file); 8458 #if 0
8150 8459 /* force a CONFIGURE event on the underlying renderbox */
8460 dw_window_get_pos_size( handle, NULL, NULL, &cx, &cy );
8461 SendMessage( handle, WM_SIZE, 0, MAKELPARAM(cx, cy) );
8462 #endif
8151 return pixmap; 8463 return pixmap;
8152 } 8464 }
8153 8465
8154 /* 8466 /*
8155 * Creates a pixmap from memory. 8467 * Creates a pixmap from memory.
8166 HPIXMAP pixmap; 8478 HPIXMAP pixmap;
8167 BITMAP bm; 8479 BITMAP bm;
8168 HDC hdc; 8480 HDC hdc;
8169 char *file; 8481 char *file;
8170 FILE *fp; 8482 FILE *fp;
8483 ULONG cx, cy;
8171 8484
8172 if ( !(pixmap = calloc(1,sizeof(struct _hpixmap))) ) 8485 if ( !(pixmap = calloc(1,sizeof(struct _hpixmap))) )
8173 { 8486 {
8174 return NULL; 8487 return NULL;
8175 } 8488 }
8211 pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight; 8524 pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight;
8212 8525
8213 SelectObject( pixmap->hdc, pixmap->hbm ); 8526 SelectObject( pixmap->hdc, pixmap->hbm );
8214 8527
8215 ReleaseDC( handle, hdc ); 8528 ReleaseDC( handle, hdc );
8529 pixmap->transcolor = DW_RGB_TRANSPARENT;
8530
8531 #if 0
8532 /* force a CONFIGURE event on the underlying renderbox */
8533 dw_window_get_pos_size( handle, NULL, NULL, &cx, &cy );
8534 SendMessage( handle, WM_SIZE, 0, MAKELPARAM(cx, cy) );
8535 #endif
8216 8536
8217 return pixmap; 8537 return pixmap;
8538 }
8539
8540 /*
8541 * Creates a bitmap mask for rendering bitmaps with transparent backgrounds
8542 */
8543 void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color )
8544 {
8545 if ( pixmap )
8546 {
8547 pixmap->transcolor = _internal_color(color);
8548 }
8218 } 8549 }
8219 8550
8220 /* 8551 /*
8221 * Creates a pixmap from internal resource graphic specified by id. 8552 * Creates a pixmap from internal resource graphic specified by id.
8222 * Parameters: 8553 * Parameters:
8259 */ 8590 */
8260 void API dw_pixmap_destroy(HPIXMAP pixmap) 8591 void API dw_pixmap_destroy(HPIXMAP pixmap)
8261 { 8592 {
8262 if(pixmap) 8593 if(pixmap)
8263 { 8594 {
8264 DeleteDC(pixmap->hdc); 8595 DeleteDC( pixmap->hdc );
8265 DeleteObject(pixmap->hbm); 8596 DeleteObject( pixmap->hbm );
8266 free(pixmap); 8597 free( pixmap );
8267 } 8598 }
8268 } 8599 }
8269 8600
8270 /* 8601 /*
8271 * Copies from one item to another. 8602 * Copies from one item to another.
8283 */ 8614 */
8284 void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc) 8615 void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
8285 { 8616 {
8286 HDC hdcdest; 8617 HDC hdcdest;
8287 HDC hdcsrc; 8618 HDC hdcsrc;
8288 8619 HDC hdcMem;
8289 if(dest) 8620
8290 hdcdest = GetDC(dest); 8621 if ( dest )
8291 else if(destp) 8622 hdcdest = GetDC( dest );
8623 else if ( destp )
8292 hdcdest = destp->hdc; 8624 hdcdest = destp->hdc;
8293 else 8625 else
8294 return; 8626 return;
8295 8627
8296 if(src) 8628 if ( src )
8297 hdcsrc = GetDC(src); 8629 hdcsrc = GetDC( src );
8298 else if(srcp) 8630 else if ( srcp )
8299 hdcsrc = srcp->hdc; 8631 hdcsrc = srcp->hdc;
8300 else 8632 else
8301 return; 8633 return;
8302 8634 if ( srcp && srcp->transcolor != DW_RGB_TRANSPARENT )
8303 BitBlt(hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, SRCCOPY); 8635 {
8304 8636 DrawTransparentBitmap( hdcdest, srcp->hdc, srcp->hbm, xdest, ydest, RGB( DW_RED_VALUE(srcp->transcolor), DW_GREEN_VALUE(srcp->transcolor), DW_BLUE_VALUE(srcp->transcolor)) );
8305 if(!destp) 8637 }
8306 ReleaseDC(dest, hdcdest); 8638 else
8307 if(!srcp) 8639 {
8308 ReleaseDC(src, hdcsrc); 8640 BitBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, SRCCOPY );
8641 }
8642 if ( !destp )
8643 ReleaseDC( dest, hdcdest );
8644 if ( !srcp )
8645 ReleaseDC( src, hdcsrc );
8309 } 8646 }
8310 8647
8311 /* Run Beep() in a separate thread so it doesn't block */ 8648 /* Run Beep() in a separate thread so it doesn't block */
8312 void _beepthread(void *data) 8649 void _beepthread(void *data)
8313 { 8650 {