# HG changeset patch # User mhessling@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1239359126 0 # Node ID c6a216c8174f6b74d9b8ed13ffb18c60cfb51d84 # Parent 87db549e79bc1560e5924b1408367de959d533d2 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() diff -r 87db549e79bc -r c6a216c8174f dw.def --- a/dw.def Tue Jan 06 11:00:15 2009 +0000 +++ b/dw.def Fri Apr 10 10:25:26 2009 +0000 @@ -62,10 +62,12 @@ dw_window_redraw @79 dw_bitmap_new @80 + dw_window_set_bitmap_from_data @81 dw_button_new @90 dw_bitmapbutton_new @91 dw_bitmapbutton_new_from_file @92 + dw_bitmapbutton_new_from_data @93 dw_text_new @100 dw_status_text_new @101 @@ -120,6 +122,7 @@ dw_icon_load @210 dw_icon_free @211 dw_icon_load_from_file @212 + dw_icon_load_from_data @213 dw_container_new @220 dw_container_setup @221 @@ -194,12 +197,15 @@ dw_draw_line @332 dw_draw_rect @333 dw_draw_text @334 + dw_draw_polygon @335 dw_pixmap_bitblt @340 dw_pixmap_new @341 dw_pixmap_grab @342 dw_pixmap_destroy @343 dw_pixmap_new_from_file @344 + dw_pixmap_new_from_data @345 + dw_pixmap_set_transparent_color @346 dw_dialog_new @350 dw_dialog_dismiss @351 @@ -271,3 +277,8 @@ dw_calendar_new @480 dw_calendar_set_date @481 dw_calendar_get_date @482 + + + dw_clipboard_get_text @490 + dw_clipboard_set_text @491 + diff -r 87db549e79bc -r c6a216c8174f dw.h --- a/dw.h Tue Jan 06 11:00:15 2009 +0000 +++ b/dw.h Fri Apr 10 10:25:26 2009 +0000 @@ -55,7 +55,14 @@ #define DW_MIS_CHECKED (1 << 2) #define DW_MIS_UNCHECKED (1 << 3) -#if defined(__OS2__) || defined(__WIN32__) || defined(__MAC__) || defined(WINNT) || defined(__EMX__) +/* ensure we can build the Gtk port with MingW on Windows */ +#if defined(DW_USE_GTK) && defined(__MINGW32__) +# ifndef GDK_WINDOWING_WIN32 +# define GDK_WINDOWING_WIN32 +# endif +#endif + +#if defined(__OS2__) || (defined(__WIN32__) && !defined(GDK_WINDOWING_WIN32)) || defined(__MAC__) || (defined(WINNT) && !defined(GDK_WINDOWING_WIN32)) || defined(__EMX__) /* OS/2, Windows or MacOS */ #if (defined(__IBMC__) || defined(_System)) && !defined(API) @@ -586,6 +593,7 @@ unsigned long width, height; HBITMAP hbm; HDC hdc; + unsigned long transcolor; HWND handle; void *bits; } *HPIXMAP; @@ -656,11 +664,17 @@ #else /* GTK Specific section */ #include -#include +#ifdef GDK_WINDOWING_X11 +# include +#else +# include +#endif #include #include #include -#include +#if !defined(GDK_WINDOWING_WIN32) +# include +#endif #define DW_DT_LEFT 1 #define DW_DT_UNDERSCORE (1 << 1) @@ -898,7 +912,7 @@ typedef CTIME *PCTIME; #endif -#if defined(__OS2__) || defined(__WIN32__) || defined(WINNT) || defined(__EMX__) +#if defined(__OS2__) || (defined(__WIN32__) && !defined(GDK_WINDOWING_WIN32)) || (defined(WINNT) && !defined(GDK_WINDOWING_WIN32)) || defined(__EMX__) typedef unsigned long DWTID; #endif @@ -1035,6 +1049,9 @@ int API dw_window_set_color(HWND handle, unsigned long fore, unsigned long back); HWND API dw_window_new(HWND hwndOwner, char *title, unsigned long flStyle); HWND API dw_box_new(int type, int pad); +#ifdef INCOMPLETE +HWND API dw_scrollbox_new(int type, int pad); +#endif HWND API dw_groupbox_new(int type, int pad, char *title); HWND API dw_mdi_new(unsigned long id); HWND API dw_bitmap_new(unsigned long id); @@ -1074,10 +1091,10 @@ unsigned int API dw_scrollbar_get_pos(HWND handle); void API dw_scrollbar_set_pos(HWND handle, unsigned int position); void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible); -void API dw_window_set_pos(HWND handle, unsigned long x, unsigned long y); +void API dw_window_set_pos(HWND handle, long x, long y); void API dw_window_set_size(HWND handle, unsigned long width, unsigned long height); -void API dw_window_set_pos_size(HWND handle, unsigned long x, unsigned long y, unsigned long width, unsigned long height); -void API dw_window_get_pos_size(HWND handle, unsigned long *x, unsigned long *y, unsigned long *width, unsigned long *height); +void API dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height); +void API dw_window_get_pos_size(HWND handle, long *x, long *y, unsigned long *width, unsigned long *height); void API dw_window_set_style(HWND handle, unsigned long style, unsigned long mask); void API dw_window_set_icon(HWND handle, unsigned long id); void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename); @@ -1168,8 +1185,7 @@ HMENUI API dw_menu_new(unsigned long id); HMENUI API dw_menubar_new(HWND location); HWND API dw_menu_append_item(HMENUI menu, char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu); -#if 0 -TBD +#ifdef INCOMPLETE void API dw_menu_delete_item(HMENUI menu, unsigned long id); #endif void API dw_menu_item_set_check(HMENUI menu, unsigned long id, int check); @@ -1209,6 +1225,7 @@ HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename); HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len); HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id); +void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color ); void API dw_pixmap_destroy(HPIXMAP pixmap); void API dw_beep(int freq, int dur); int API dw_messagebox(char *title, int flags, char *format, ...); diff -r 87db549e79bc -r c6a216c8174f dwtest.c --- a/dwtest.c Tue Jan 06 11:00:15 2009 +0000 +++ b/dwtest.c Fri Apr 10 10:25:26 2009 +0000 @@ -126,6 +126,7 @@ textbox1, textbox2, textboxA, gap_box, buttonbox, + buttonsbox, buttonboxperm, cal, filetoolbarbox; @@ -480,14 +481,32 @@ int DWSIGNAL redraw_button_box_callback(HWND window, void *data) { #if 0 + + long x, y, width, height; + dw_window_get_pos_size(filetoolbarbox , &x, &y, &width, &height); dw_window_destroy( filetoolbarbox ); create_button(1); + dw_window_set_pos_size(filetoolbarbox, x, y, width, height); #else dw_window_enable( window); + dw_menu_delete_item( changeable_menu, NONCHECKABLE_MENUITEMID ); #endif return 0; } +int DWSIGNAL change_color_red_callback(HWND window, void *data) +{ + dw_window_set_color(buttonsbox, DW_CLR_RED, DW_CLR_RED); + return 0; +} + +int DWSIGNAL change_color_yellow_callback(HWND window, void *data) +{ + dw_window_set_color(buttonsbox, DW_CLR_YELLOW, DW_CLR_YELLOW); + return 0; +} + + /* Callback to handle user selection of the scrollbar position */ void DWSIGNAL scrollbar_valuechanged_callback(HWND hwnd, int value, void *data) { @@ -902,12 +921,13 @@ void buttons_add(void) { - HWND buttonsbox,abutton1,abutton2,calbox,bw; + HWND abutton1,abutton2,calbox,bw; int i; char buf[20]; char **text; /* create a box to pack into the notebook page */ +// buttonsbox = dw_scrollbox_new(BOXVERT, 2); buttonsbox = dw_box_new(BOXVERT, 2); dw_box_pack_start( notebookbox5, buttonsbox, 25, 200, TRUE, TRUE, 0); dw_window_set_color(buttonsbox, DW_CLR_RED, DW_CLR_RED); @@ -925,7 +945,8 @@ buttonboxperm = dw_box_new( BOXVERT, 0 ); dw_box_pack_start( buttonsbox, buttonboxperm, 25, 0, FALSE, TRUE, 2 ); dw_window_set_color(buttonboxperm, DW_CLR_WHITE, DW_CLR_WHITE); - abutton1 = dw_bitmapbutton_new_from_file( "Top Button", 0, FILE_ICON_NAME ); +// abutton1 = dw_bitmapbutton_new_from_file( "Top Button", 0, FILE_ICON_NAME ); + abutton1 = dw_bitmapbutton_new_from_file( "Top Button", 0, "z:\\projects\\RexxGd\\regina\\tile_up.png" ); dw_box_pack_start( buttonboxperm, abutton1, 100, 30, FALSE, FALSE, 0 ); dw_signal_connect( abutton1, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(button_callback), NULL ); dw_box_pack_start( buttonboxperm, 0, 25, 5, FALSE, FALSE, 0 ); @@ -996,12 +1017,12 @@ abutton1 = dw_bitmapbutton_new_from_file( "Should be under Top button", 0, "junk" ); dw_box_pack_start( filetoolbarbox, abutton1, 25, 25, FALSE, FALSE, 0); - dw_signal_connect( abutton1, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(redraw_button_box_callback), NULL ); + dw_signal_connect( abutton1, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(change_color_red_callback), NULL ); dw_box_pack_start( filetoolbarbox, 0, 25, 5, FALSE, FALSE, 0 ); abutton1 = dw_bitmapbutton_new_from_file( "Should be under Top button", 0, "junk" ); dw_box_pack_start( filetoolbarbox, abutton1, 25, 25, FALSE, FALSE, 0); - dw_signal_connect( abutton1, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(redraw_button_box_callback), NULL ); + dw_signal_connect( abutton1, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(change_color_yellow_callback), NULL ); dw_box_pack_start( filetoolbarbox, 0, 25, 5, FALSE, FALSE, 0 ); abutton1 = dw_bitmapbutton_new_from_file( "Should be under Top button", 0, "junk" ); @@ -1167,7 +1188,7 @@ dw_html_url(html, "http://www.rexx.org"); dw_signal_connect(mainwindow, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(exit_callback), (void *)mainwindow); - timerid = dw_timer_connect(1000, DW_SIGNAL_FUNC(timer_callback), 0); + timerid = dw_timer_connect(2000, DW_SIGNAL_FUNC(timer_callback), 0); dw_window_set_size(mainwindow, 640, 520); dw_window_show(mainwindow); diff -r 87db549e79bc -r c6a216c8174f dww-mingw.def --- a/dww-mingw.def Tue Jan 06 11:00:15 2009 +0000 +++ b/dww-mingw.def Fri Apr 10 10:25:26 2009 +0000 @@ -59,10 +59,12 @@ dw_window_redraw @79 dw_bitmap_new @80 + dw_window_set_bitmap_from_data @81 dw_button_new @90 dw_bitmapbutton_new @91 dw_bitmapbutton_new_from_file @92 + dw_bitmapbutton_new_from_data @93 dw_text_new @100 dw_status_text_new @101 @@ -117,6 +119,7 @@ dw_icon_load @210 dw_icon_free @211 dw_icon_load_from_file @212 + dw_icon_load_from_data @213 dw_container_new @220 dw_container_setup @221 @@ -146,9 +149,10 @@ dw_screen_width @250 dw_screen_height @251 - dw_color_depth_get @260 + dw_color_depth_get @260 dw_color_foreground_set @261 dw_color_background_set @262 + dw_color_choose @263 dw_notebook_new @270 dw_notebook_page_new @271 @@ -190,12 +194,15 @@ dw_draw_line @332 dw_draw_rect @333 dw_draw_text @334 + dw_draw_polygon @335 dw_pixmap_bitblt @340 dw_pixmap_new @341 dw_pixmap_grab @342 dw_pixmap_destroy @343 dw_pixmap_new_from_file @344 + dw_pixmap_new_from_data @345 + dw_pixmap_set_transparent_color @346 dw_dialog_new @350 dw_dialog_dismiss @351 @@ -258,3 +265,17 @@ dw_named_event_post @463 dw_named_event_wait @464 dw_named_event_close @465 + + dw_html_new @470 + dw_html_action @471 + dw_html_raw @472 + dw_html_url @473 + + dw_calendar_new @480 + dw_calendar_set_date @481 + dw_calendar_get_date @482 + + + dw_clipboard_get_text @490 + dw_clipboard_set_text @491 + diff -r 87db549e79bc -r c6a216c8174f dww.def --- a/dww.def Tue Jan 06 11:00:15 2009 +0000 +++ b/dww.def Fri Apr 10 10:25:26 2009 +0000 @@ -194,6 +194,7 @@ dw_draw_line @332 dw_draw_rect @333 dw_draw_text @334 + dw_draw_polygon @335 dw_pixmap_bitblt @340 dw_pixmap_new @341 @@ -201,6 +202,7 @@ dw_pixmap_destroy @343 dw_pixmap_new_from_file @344 dw_pixmap_new_from_data @345 + dw_pixmap_set_transparent_color @346 dw_dialog_new @350 dw_dialog_dismiss @351 diff -r 87db549e79bc -r c6a216c8174f makefile.vc --- a/makefile.vc Tue Jan 06 11:00:15 2009 +0000 +++ b/makefile.vc Fri Apr 10 10:25:26 2009 +0000 @@ -10,13 +10,21 @@ FXLIBDIR=.\lib FXDLLDIR=.\dll +!if "$(DEBUG)" == "Y" +CFLAGS_DEBUG = -Z7 -Od # was -Zi +LINK_DEBUG = -debug:full +!else +CFLAGS_DEBUG = -Ox +LINK_DEBUG = -release +!endif + CC = cl CFLAGS = -c -G5 -GD -Zp1 -DWIN32 -D__WIN32__ -DMSVC -DBUILD_DLL -I$(SRCDIR)\platform -I$(SRCDIR) -CFLAGS_DEBUG = -Zi -CFLAGS_COMPILE = -MTd +#CFLAGS_COMPILE = -MTd +CFLAGS_COMPILE = -MD LIBS = wsock32.lib kernel32.lib user32.lib comctl32.lib gdi32.lib advapi32.lib shell32.lib comdlg32.lib ole32.lib oleaut32.lib RES = -LINKFLAGS = -machine:i386 -debug:full +LINKFLAGS = -machine:i386 $(LINK_DEBUG) DLLLINKFLAGS = -dll LINK = link DEFFILE = $(SRCDIR)\dww.def diff -r 87db549e79bc -r c6a216c8174f win/dw.c --- a/win/dw.c Tue Jan 06 11:00:15 2009 +0000 +++ b/win/dw.c Fri Apr 10 10:25:26 2009 +0000 @@ -67,6 +67,7 @@ HPEN _hPen[THREAD_LIMIT]; HBRUSH _hBrush[THREAD_LIMIT]; char *_clipboard_contents[THREAD_LIMIT]; +int _PointerOnWnd[THREAD_LIMIT]; BYTE _red[] = { 0x00, 0xbb, 0x00, 0xaa, 0x00, 0xbb, 0x00, 0xaa, 0x77, 0xff, 0x00, 0xee, 0x00, 0xff, 0x00, 0xff, 0xaa, 0x00 }; @@ -77,6 +78,7 @@ HBRUSH _colors[18]; +static int screenx, screeny; LRESULT CALLBACK _browserWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void _resize_notebook_page(HWND handle, int pageid); @@ -261,6 +263,107 @@ return isnt; } +void DrawTransparentBitmap(HDC hdc, HDC hdcSrc, HBITMAP hBitmap, int xStart, int yStart, COLORREF cTransparentColor) +{ + BITMAP bm; + COLORREF cColor; + HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave; + HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld; + HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave; + POINT ptSize; + +#if 0 + hdcTemp = CreateCompatibleDC(hdc); + SelectObject(hdcTemp, hBitmap); // Select the bitmap +#else + hdcTemp = hdcSrc; +#endif + + GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); + ptSize.x = bm.bmWidth; // Get width of bitmap + ptSize.y = bm.bmHeight; // Get height of bitmap + DPtoLP(hdcTemp, &ptSize, 1); // Convert from device + + // to logical points + + // Create some DCs to hold temporary data. + hdcBack = CreateCompatibleDC(hdc); + hdcObject = CreateCompatibleDC(hdc); + hdcMem = CreateCompatibleDC(hdc); + hdcSave = CreateCompatibleDC(hdc); + + // Create a bitmap for each DC. DCs are required for a number of + // GDI functions. + + // Monochrome DC + bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); + + // Monochrome DC + bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); + + bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); + bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); + + // Each DC must select a bitmap object to store pixel data. + bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack); + bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject); + bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem); + bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave); + + // Set proper mapping mode. + SetMapMode(hdcTemp, GetMapMode(hdc)); + + // Save the bitmap sent here, because it will be overwritten. + BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); + + // Set the background color of the source DC to the color. + // contained in the parts of the bitmap that should be transparent + cColor = SetBkColor(hdcTemp, cTransparentColor); + + // Create the object mask for the bitmap by performing a BitBlt + // from the source bitmap to a monochrome bitmap. + BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); + + // Set the background color of the source DC back to the original + // color. + SetBkColor(hdcTemp, cColor); + + // Create the inverse of the object mask. + BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY); + + // Copy the background of the main DC to the destination. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY); + + // Mask out the places where the bitmap will be placed. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND); + + // Mask out the transparent colored pixels on the bitmap. + BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND); + + // XOR the bitmap with the background on the destination DC. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT); + + // Copy the destination to the screen. + BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, + SRCCOPY); + + // Place the original bitmap back into the bitmap sent here. + BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY); + + // Delete the memory bitmaps. + DeleteObject(SelectObject(hdcBack, bmBackOld)); + DeleteObject(SelectObject(hdcObject, bmObjectOld)); + DeleteObject(SelectObject(hdcMem, bmMemOld)); + DeleteObject(SelectObject(hdcSave, bmSaveOld)); + + // Delete the memory DCs. + DeleteDC(hdcMem); + DeleteDC(hdcBack); + DeleteDC(hdcObject); + DeleteDC(hdcSave); + DeleteDC(hdcTemp); +} + DWORD GetDllVersion(LPCTSTR lpszDllName) { @@ -1303,8 +1406,10 @@ Box *boxinfo = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA); if(boxinfo && boxinfo->grouphwnd) + { MoveWindow(boxinfo->grouphwnd, 0, 0, width + vectorx, height + vectory, FALSE); + } } } @@ -1513,7 +1618,6 @@ case WM_SIZE: { int (*sizefunc)(HWND, int, int, void *) = tmp->signalfunction; - if(hWnd == tmp->window) { result = sizefunc(tmp->window, LOWORD(mp2), HIWORD(mp2), tmp->data); @@ -1653,7 +1757,7 @@ DWExpose exp; int (*exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction; - if(hWnd == tmp->window) + if ( hWnd == tmp->window ) { BeginPaint(hWnd, &ps); exp.x = ps.rcPaint.left; @@ -1833,8 +1937,8 @@ result = clickfunc(tmp->window, tmp->data); tmp = NULL; } - } /* Make sure it's the right window, and the right ID */ - else if (tmp->window < (HWND)65536 && command == tmp->window) + } /* this fires for checkable menu items */ + else if ( tmp->window < (HWND)65536 && command == tmp->window && tmp->message != WM_TIMER ) { _dw_toggle_checkable_menu_item( popup ? popup : tmp->window, (int)tmp->data ); result = clickfunc(popup ? popup : tmp->window, tmp->data); @@ -1846,7 +1950,7 @@ case WM_VSCROLL: { char tmpbuf[100]; - HWND handle = (HWND)mp2; + HWND handle = (HWND)mp2; int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction; GetClassName(handle, tmpbuf, 99); @@ -1983,6 +2087,7 @@ case WM_VSCROLL: { HWND handle = (HWND)mp2; + char tmpbuf[100]; if(dw_window_get_data(handle, "_dw_scrollbar")) { @@ -1991,7 +2096,11 @@ if(value > -1) dw_scrollbar_set_pos(handle, value); } - } + GetClassName( hWnd, tmpbuf, 99 ); + if ( strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1 ) == 0 ) + { + int value = _HandleScroller(hWnd, (int)HIWORD(mp1), (int)LOWORD(mp1)); + } } break; case WM_GETMINMAXINFO: { @@ -2096,7 +2205,9 @@ if(result != -1) return result; else + { return DefWindowProc(hWnd, msg, mp1, mp2); + } } VOID CALLBACK _TimerProc(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime) @@ -2204,6 +2315,12 @@ BOOL CALLBACK _rendwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) { + RECT wndRect; + POINTS points; + POINT point; + int threadid = dw_thread_id(); + + switch( msg ) { case WM_LBUTTONDOWN: @@ -2212,10 +2329,41 @@ SetFocus(hWnd); _wndproc(hWnd, msg, mp1, mp2); break; + case WM_MOUSEMOVE: + if ( threadid < 0 || threadid >= THREAD_LIMIT ) + threadid = 0; + /* + * Set the mouse capture and focus on the renderbox + * when the mouse moves into the window. + */ + points = MAKEPOINTS(mp2); /* get the mouse point */ + point.x = points.x; + point.y = points.y; + SetCapture( hWnd ); /* Capture the mouse input */ + + GetWindowRect( hWnd, &wndRect ); + ClientToScreen( hWnd, &point ); + + if ( PtInRect( &wndRect, point ) ) + { // Test if the pointer is on the window + + if ( _PointerOnWnd[threadid] == 0 ) + { + SetFocus(hWnd); + _PointerOnWnd[threadid] = 1; + } + } + else + { + ReleaseCapture(); + _PointerOnWnd[threadid] = 0; + } + /* call our standard Windows procedure */ + _wndproc(hWnd, msg, mp1, mp2); + break; case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: - case WM_MOUSEMOVE: case WM_PAINT: case WM_SIZE: case WM_COMMAND: @@ -2989,13 +3137,30 @@ { BubbleButton *bubble; static int bMouseOver = 0; + static BubbleButton *this_bubble = NULL; POINT point; RECT rect; WNDPROC pOldProc; bubble = (BubbleButton *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - - if(!bubble) + if ( bubble != this_bubble ) + { + /* + * If we missed the release capture, then if the bubble details + * from this window are different from the last we must be in a + * different button, so delete the last bubble text + */ + bMouseOver = 0; + this_bubble = bubble; + if ( hwndBubble ) + { + _free_window_memory(hwndBubble, 0); + DestroyWindow(hwndBubble); + hwndBubble = 0; + } + } + + if ( !bubble ) return DefWindowProc(hwnd, msg, mp1, mp2); /* We must save a pointer to the old @@ -3022,6 +3187,16 @@ case WM_LBUTTONUP: { SignalHandler *tmp = Root; + /* + * If we have bubbletext displaying when we + * release the mouse, get rid of the bubbletext window + */ + if ( hwndBubble ) + { + _free_window_memory(hwndBubble, 0); + DestroyWindow(hwndBubble); + hwndBubble = 0; + } /* Find any callbacks for this function */ while(tmp) @@ -3095,13 +3270,13 @@ GetCursorPos(&point); GetWindowRect(hwnd, &rect); - if(PtInRect(&rect, point)) - { - if(hwnd != GetCapture()) + if ( PtInRect(&rect, point) ) + { + if ( hwnd != GetCapture() ) { SetCapture(hwnd); } - if(!bMouseOver) + if ( !bMouseOver ) { bMouseOver = 1; if(!*bubble->bubbletext) @@ -3190,7 +3365,7 @@ * Either because we intentionally lost it or another window * stole it */ - if(bMouseOver && hwndBubble) + if ( bMouseOver && hwndBubble ) { bMouseOver = 0; _free_window_memory(hwndBubble, 0); @@ -3200,7 +3375,7 @@ break; } - if(!pOldProc) + if ( !pOldProc ) return DefWindowProc(hwnd, msg, mp1, mp2); return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2); } @@ -3268,6 +3443,11 @@ *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); windowtype = BS_BITMAP; } + else if ( stricmp( file + len - 4, ".png" ) == 0 ) + { + *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); + windowtype = BS_BITMAP; + } free(file); } else @@ -3405,6 +3585,7 @@ _hPen[z] = CreatePen(PS_SOLID, 1, _foreground[z]); _hBrush[z] = CreateSolidBrush(_foreground[z]); _clipboard_contents[z] = NULL; + _PointerOnWnd[z] = 0; } if ( !IS_WINNTOR95 ) @@ -3429,6 +3610,13 @@ { dbgfp = fopen( fname, "w" ); } + /* + * Get screen size. Used to make calls to dw_screen_width() + * and dw_screen-height() quicker, but to alos limit the + * default size of windows. + */ + screenx = GetSystemMetrics(SM_CXSCREEN); + screeny = GetSystemMetrics(SM_CYSCREEN); return 0; } @@ -3865,9 +4053,11 @@ int API dw_window_set_color(HWND handle, ULONG fore, ULONG back) { ColorInfo *cinfo; + Box *newbox; char tmpbuf[100]; cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA); + newbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA); GetClassName(handle, tmpbuf, 99); @@ -4043,6 +4233,40 @@ } /* + * INCOMPLETE + * Create a new scroll Box to be packed. + * Parameters: + * type: Either DW_VERT (vertical) or DW_HORZ (horizontal). + * pad: Number of pixels to pad around the box. + */ +HWND API dw_scrollbox_new(int type, int pad) +{ + Box *newbox = calloc(sizeof(Box), 1); + HWND hwndframe; + + newbox->pad = pad; + newbox->type = type; + newbox->count = 0; + newbox->grouphwnd = (HWND)NULL; + newbox->cinfo.fore = newbox->cinfo.back = -1; + + hwndframe = CreateWindow(FRAMECLASSNAME, + "", + WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL, + 0,0,2000,1000, + DW_HWND_OBJECT, + NULL, + DWInstance, + NULL); + + newbox->cinfo.pOldProc = SubclassWindow(hwndframe, _colorwndproc); + newbox->cinfo.fore = newbox->cinfo.back = -1; + + SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox); + return hwndframe; +} + +/* * Create a new Group Box to be packed. * Parameters: * type: Either DW_VERT (vertical) or DW_HORZ (horizontal). @@ -4457,9 +4681,8 @@ dw_window_set_data( DW_HWND_OBJECT, buffer2, (void *)disabled ); } -#if 0 -/* - * TBD +/* + * INCOMPLETE * Deletes the menu item specified * Parameters: * menu: The handle to the menu in which the item was appended. @@ -4469,13 +4692,17 @@ { HMENU mymenu = (HMENU)menux; - if(IsWindow(menux) && !IsMenu(mymenu)) + if ( IsWindow(menux) && !IsMenu(mymenu) ) mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu"); - DeleteMenu(mymenu, id, MF_BYCOMMAND); + if ( DeleteMenu(mymenu, id, MF_BYCOMMAND) == 0 ) + { + char lasterror[257]; + FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), lasterror, 256, NULL); + fprintf(stderr, "Error deleting menu: %s", lasterror); + } DrawMenuBar(menux); } -#endif /* * Pops up a context menu at given x and y coordinates. @@ -4855,15 +5082,11 @@ if(icon) { - SendMessage(tmp, BM_SETIMAGE, - (WPARAM) IMAGE_ICON, - (LPARAM) icon); + SendMessage(tmp, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) icon); } else if(hbitmap) { - SendMessage(tmp, BM_SETIMAGE, - (WPARAM) IMAGE_BITMAP, - (LPARAM) hbitmap); + SendMessage(tmp, BM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap); } return tmp; } @@ -4892,8 +5115,6 @@ tmp = CreateWindow( BUTTONCLASSNAME, "", -// label_text, -// WS_CHILD | BS_OWNERDRAW | WS_CLIPCHILDREN | WS_VISIBLE, windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE, 0,0,2000,1000, DW_HWND_OBJECT, @@ -4987,15 +5208,11 @@ if ( icon ) { - SendMessage( tmp, BM_SETIMAGE, - (WPARAM) IMAGE_ICON, - (LPARAM) icon); + SendMessage( tmp, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) icon); } else if( hbitmap ) { - SendMessage( tmp, BM_SETIMAGE, - (WPARAM) IMAGE_BITMAP, - (LPARAM) hbitmap); + SendMessage( tmp, BM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap); } return tmp; } @@ -5367,6 +5584,7 @@ */ void API dw_window_set_text(HWND handle, char *text) { + Box *thisbox; char tmpbuf[100]; GetClassName(handle, tmpbuf, 99); @@ -5374,8 +5592,15 @@ SetWindowText(handle, text); /* Combobox */ - if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0) + if ( strnicmp( tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1) == 0 ) SendMessage(handle, CB_SETEDITSEL, 0, MAKELPARAM(-1, 0)); + else if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1) == 0 ) + { + /* groupbox */ + thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA ); + if ( thisbox && thisbox->grouphwnd != (HWND)NULL ) + SetWindowText( thisbox->grouphwnd, text ); + } } /* @@ -5567,6 +5792,10 @@ if ( width == 0 ) width = usedx; if ( height == 0 ) height = usedy; SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE); +#if 0 + /* force a configure event */ + SendMessage( handle, WM_SIZE, 0, MAKELPARAM(usedx, usedy) ); +#endif } /* @@ -5574,7 +5803,7 @@ */ int API dw_screen_width(void) { - return GetSystemMetrics(SM_CXSCREEN); + return screenx; } /* @@ -5582,7 +5811,7 @@ */ int API dw_screen_height(void) { - return GetSystemMetrics(SM_CYSCREEN); + return screeny; } /* This should return the current color depth */ @@ -5606,7 +5835,7 @@ * x: X location from the bottom left. * y: Y location from the bottom left. */ -void API dw_window_set_pos(HWND handle, ULONG x, ULONG y) +void API dw_window_set_pos(HWND handle, long x, long y) { SetWindowPos(handle, (HWND)NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } @@ -5620,7 +5849,7 @@ * width: Width of the widget. * height: Height of the widget. */ -void API dw_window_set_pos_size(HWND handle, ULONG x, ULONG y, ULONG width, ULONG height) +void API dw_window_set_pos_size(HWND handle, long x, long y, ULONG width, ULONG height) { int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0; Box *thisbox; @@ -5635,7 +5864,13 @@ _resize_box(thisbox, &depth, 0, 0, &usedx, &usedy, 1, &usedpadx, &usedpady); _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady); } + if ( width == 0 ) width = usedx; + if ( height == 0 ) height = usedy; SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE); +#if 0 + /* force a configure event */ + SendMessage( handle, WM_SIZE, 0, MAKELPARAM(width, height) ); +#endif } /* @@ -5647,7 +5882,7 @@ * width: Width of the widget. * height: Height of the widget. */ -void API dw_window_get_pos_size(HWND handle, ULONG *x, ULONG *y, ULONG *width, ULONG *height) +void API dw_window_get_pos_size(HWND handle, long *x, long *y, ULONG *width, ULONG *height) { WINDOWPLACEMENT wp; @@ -5665,7 +5900,7 @@ if(height) *height=dw_screen_height(); } -else + else { if(x) *x = wp.rcNormalPosition.left; @@ -7750,7 +7985,7 @@ HWND tmp = CreateWindow(ObjectClassName, "", WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN, - 0,0,2000,1000, + 0,0,screenx,screeny, DW_HWND_OBJECT, (HMENU)id, DWInstance, @@ -7761,8 +7996,7 @@ newbox->grouphwnd = (HWND)NULL; newbox->cinfo.pOldProc = SubclassWindow(tmp, _rendwndproc); newbox->cinfo.fore = newbox->cinfo.back = -1; - - SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)newbox); + SetWindowLongPtr( tmp, GWLP_USERDATA, (LONG_PTR)newbox ); return tmp; } @@ -7901,6 +8135,73 @@ ReleaseDC(handle, hdcPaint); } +/* Draw a closed polygon on a window (preferably a render window). + * Parameters: + * handle: Handle to the window. + * pixmap: Handle to the pixmap. (choose only one of these) + * fill: if true filled + * number of points + * x[]: X coordinates. + * y[]: Y coordinates. + */ +void API dw_draw_polygon(HWND handle, HPIXMAP pixmap, int fill, int npoints, int *x, int *y) +{ + HDC hdcPaint; + HBRUSH oldBrush; + HPEN oldPen; + POINT *points; + int i; + int threadid = dw_thread_id(); + + if(threadid < 0 || threadid >= THREAD_LIMIT) + threadid = 0; + + if ( handle ) + hdcPaint = GetDC( handle ); + else if ( pixmap ) + hdcPaint = pixmap->hdc; + else + return; + if ( npoints ) + { + /* + * Allocate enough space for the number of points supplied plus 1. + * Under windows, unless the first and last points are the same + * the polygon won't be closed + */ + points = (POINT *)malloc( (npoints+1) * sizeof(POINT) ); + /* + * should check for NULL pointer return! + */ + for ( i = 0 ; i < npoints ; i++ ) + { + points[i].x = x[i]; + points[i].y = y[i]; + } + if ( !( points[0].x == points[npoints-1].x + && points[0].y == points[npoints-1].y ) ) + { + /* set the last point to be the same as the first point... */ + points[npoints].x = points[0].x; + points[npoints].y = points[0].y; + /* ... and increment the number of points */ + npoints++; + } + } + + oldBrush = SelectObject( hdcPaint, _hBrush[threadid] ); + oldPen = SelectObject( hdcPaint, _hPen[threadid] ); + if ( fill ) + Polygon( hdcPaint, points, npoints ); + else + Polyline( hdcPaint, points, npoints ); + SelectObject( hdcPaint, oldBrush ); + SelectObject( hdcPaint, oldPen ); + if ( !pixmap ) + ReleaseDC( handle, hdcPaint ); + free(points); +} + /* Draw a rectangle on a window (preferably a render window). * Parameters: * handle: Handle to the window. @@ -8065,6 +8366,8 @@ { HPIXMAP pixmap; HDC hdc; + COLORREF bkcolor; + ULONG cx, cy; if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) return NULL; @@ -8076,11 +8379,18 @@ pixmap->handle = handle; pixmap->hbm = CreateCompatibleBitmap(hdc, width, height); pixmap->hdc = CreateCompatibleDC(hdc); + pixmap->transcolor = DW_RGB_TRANSPARENT; SelectObject(pixmap->hdc, pixmap->hbm); ReleaseDC(handle, hdc); +#if 0 + /* force a CONFIGURE event on the underlying renderbox */ + dw_window_get_pos_size( handle, NULL, NULL, &cx, &cy ); + SendMessage( handle, WM_SIZE, 0, MAKELPARAM(cx, cy) ); +#endif + return pixmap; } @@ -8099,6 +8409,7 @@ HPIXMAP pixmap; BITMAP bm; HDC hdc; + ULONG cx, cy; char *file = malloc(strlen(filename) + 5); if (!file || !(pixmap = calloc(1,sizeof(struct _hpixmap)))) @@ -8128,7 +8439,7 @@ pixmap->handle = handle; pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); - if(!pixmap->hbm) + if ( !pixmap->hbm ) { free(file); free(pixmap); @@ -8136,18 +8447,19 @@ return NULL; } - pixmap->hdc = CreateCompatibleDC(hdc); - - GetObject(pixmap->hbm, sizeof(bm), &bm); - + pixmap->hdc = CreateCompatibleDC( hdc ); + GetObject( pixmap->hbm, sizeof(bm), &bm ); pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight; - - SelectObject(pixmap->hdc, pixmap->hbm); - - ReleaseDC(handle, hdc); - - free(file); - + SelectObject( pixmap->hdc, pixmap->hbm ); + ReleaseDC( handle, hdc ); + free( file ); + pixmap->transcolor = DW_RGB_TRANSPARENT; + +#if 0 + /* force a CONFIGURE event on the underlying renderbox */ + dw_window_get_pos_size( handle, NULL, NULL, &cx, &cy ); + SendMessage( handle, WM_SIZE, 0, MAKELPARAM(cx, cy) ); +#endif return pixmap; } @@ -8168,6 +8480,7 @@ HDC hdc; char *file; FILE *fp; + ULONG cx, cy; if ( !(pixmap = calloc(1,sizeof(struct _hpixmap))) ) { @@ -8213,11 +8526,29 @@ SelectObject( pixmap->hdc, pixmap->hbm ); ReleaseDC( handle, hdc ); + pixmap->transcolor = DW_RGB_TRANSPARENT; + +#if 0 + /* force a CONFIGURE event on the underlying renderbox */ + dw_window_get_pos_size( handle, NULL, NULL, &cx, &cy ); + SendMessage( handle, WM_SIZE, 0, MAKELPARAM(cx, cy) ); +#endif return pixmap; } /* + * Creates a bitmap mask for rendering bitmaps with transparent backgrounds + */ +void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color ) +{ + if ( pixmap ) + { + pixmap->transcolor = _internal_color(color); + } +} + +/* * Creates a pixmap from internal resource graphic specified by id. * Parameters: * handle: Window handle the pixmap is associated with. @@ -8261,9 +8592,9 @@ { if(pixmap) { - DeleteDC(pixmap->hdc); - DeleteObject(pixmap->hbm); - free(pixmap); + DeleteDC( pixmap->hdc ); + DeleteObject( pixmap->hbm ); + free( pixmap ); } } @@ -8285,27 +8616,33 @@ { HDC hdcdest; HDC hdcsrc; - - if(dest) - hdcdest = GetDC(dest); - else if(destp) + HDC hdcMem; + + if ( dest ) + hdcdest = GetDC( dest ); + else if ( destp ) hdcdest = destp->hdc; else return; - if(src) - hdcsrc = GetDC(src); - else if(srcp) + if ( src ) + hdcsrc = GetDC( src ); + else if ( srcp ) hdcsrc = srcp->hdc; else return; - - BitBlt(hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, SRCCOPY); - - if(!destp) - ReleaseDC(dest, hdcdest); - if(!srcp) - ReleaseDC(src, hdcsrc); + if ( srcp && srcp->transcolor != DW_RGB_TRANSPARENT ) + { + DrawTransparentBitmap( hdcdest, srcp->hdc, srcp->hbm, xdest, ydest, RGB( DW_RED_VALUE(srcp->transcolor), DW_GREEN_VALUE(srcp->transcolor), DW_BLUE_VALUE(srcp->transcolor)) ); + } + else + { + BitBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, SRCCOPY ); + } + if ( !destp ) + ReleaseDC( dest, hdcdest ); + if ( !srcp ) + ReleaseDC( src, hdcsrc ); } /* Run Beep() in a separate thread so it doesn't block */