2 * ROSky - SkyOS Application Layer
3 * Copyright (C) 2004 ReactOS Team
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * PROJECT: SkyOS GI library
22 * FILE: lib/libskygi/libskygi.c
23 * PURPOSE: SkyOS GI library
42 } SKY_WINDOW
, *PSKY_WINDOW
;
48 } SKY_MENU
, *PSKY_MENU
;
52 widget_menu_item MenuItem
;
53 MENUITEMINFOW MenuItemInfo
;
54 } SKY_MENUITEM
, *PSKY_MENUITEM
;
69 static ATOM SkyClassAtom
;
70 static BOOL SkyClassRegistered
= FALSE
;
73 * Map a SkyOS window style to Windows one.
75 * @param SkyStyle SkyOS window style (WF_* flags).
76 * @param ExStyle Contains Windows extended window style on exit.
78 * @return Windows window style (WS_* flags).
81 * WF_MODAL, WF_HAS_MENU, WF_HAS_STATUSBAR, WF_FREEFORM, WF_FOCUSABLE,
82 * WF_USER, WF_DESKTOP, WF_NOT_MOVEABLE, WF_NO_BUTTONS, WF_TRANSPARENT,
83 * WF_NO_INITIAL_DRAW, WF_USE_BACKGROUND, WF_DONT_EREASE_BACKGROUND,
87 IntMapWindowStyle(ULONG SkyStyle
, ULONG
*ExStyle
)
91 Style
= (SkyStyle
& WF_HIDE
) ? 0 : WS_VISIBLE
;
92 Style
|= (SkyStyle
& WF_NO_TITLE
) ? 0 : WS_CAPTION
;
93 Style
|= (SkyStyle
& WF_NOT_SIZEABLE
) ? WS_THICKFRAME
: 0;
94 Style
|= (SkyStyle
& WF_POPUP
) ? WS_POPUP
: 0;
95 Style
|= (SkyStyle
& WF_NO_BUTTONS
) ? 0 :
96 ((SkyStyle
& WF_NOT_SIZEABLE
) ? 0 : WS_MAXIMIZEBOX
) |
97 WS_MINIMIZEBOX
| WS_SYSMENU
;
98 *ExStyle
= (SkyStyle
& WF_SMALL_TITLE
) ? WS_EX_TOOLWINDOW
: 0;
105 * Dispatch a Sky Message to the appropriate window callback
107 * @param win Specifies the destination window
108 * @param type The type of the message (see MSG_ constants)
109 * @param para1 Additional parameter 1
110 * @param para2 Additional parameter 2
112 * @return Returns the return value of the window callback function
115 IntDispatchMsg(s_window
*win
, unsigned int type
, unsigned int para1
, unsigned int para2
)
120 /* fill the members of the struct */
125 msg
.next
= NULL
; /* ??? */
126 msg
.prev
= NULL
; /* ??? */
128 msg
.timestamp
= (unsigned long long)GetTickCount() * 1000LL;
130 DBG("Dispatching window (0x%x) message type %d\n", win
, type
);
131 Ret
= win
->win_func(win
, &msg
);
132 DBG("Dispatched window (0x%x) message type %d, returned 0x%x\n", win
, type
, Ret
);
138 * Dispatch a Sky Message with a update rect to the appropriate window callback
140 * @param win Specifies the destination window
141 * @param type The type of the message (see MSG_ constants)
142 * @param para1 Additional parameter 1
143 * @param para2 Additional parameter 2
144 * @param rect Rectangle of the window to be repainted
146 * @return Returns the return value of the window callback function
149 IntDispatchMsgRect(s_window
*win
, unsigned int type
, unsigned int para1
, unsigned int para2
, s_region
*rect
)
154 /* fill the members of the struct */
159 msg
.next
= NULL
; /* ??? */
160 msg
.prev
= NULL
; /* ??? */
163 msg
.timestamp
= (unsigned long long)GetTickCount() * 1000LL;
165 DBG("Dispatching window (0x%x) message type %d\n", win
, type
);
166 Ret
= win
->win_func(win
, &msg
);
167 DBG("Dispatched window (0x%x) message type %d, returned 0x%x\n", win
, type
, Ret
);
173 * Determines whether a win32 message should cause a Sky message to be dispatched
175 * @param skw Specifies the destination window
176 * @param Msg Contains the win32 message
177 * @param smsg Address to the sky message structure that will be filled in with
178 * appropriate information in case a sky message should be dispatched
180 * @return Returns TRUE if a Sky message should be dispatched
183 IntIsSkyMessage(PSKY_WINDOW skw
, MSG
*Msg
, s_gi_msg
*smsg
)
190 smsg
->type
= MSG_DESTROY
;
200 if(GetUpdateRect(skw
->hWnd
, &rc
, FALSE
))
202 BeginPaint(skw
->hWnd
, &ps
);
203 EndPaint(skw
->hWnd
, &ps
);
205 smsg
->type
= MSG_GUI_REDRAW
;
209 smsg
->rect
.x1
= rc
.left
;
210 smsg
->rect
.y1
= rc
.top
;
211 smsg
->rect
.x2
= rc
.right
;
212 smsg
->rect
.y2
= rc
.bottom
;
220 smsg
->type
= MSG_QUIT
;
226 smsg
->type
= MSG_COMMAND
;
227 smsg
->para1
= LOWORD(Msg
->wParam
);
233 smsg
->type
= MSG_MOUSE_MOVED
;
234 goto DoMouseInputMessage
;
239 smsg
->type
= MSG_MOUSE_BUT1_PRESSED
;
240 goto DoMouseInputMessage
;
243 smsg
->type
= MSG_MOUSE_BUT1_RELEASED
;
244 goto DoMouseInputMessage
;
247 smsg
->type
= MSG_MOUSE_BUT2_PRESSED
;
248 goto DoMouseInputMessage
;
254 smsg
->type
= MSG_MOUSE_BUT2_RELEASED
;
258 pt
.x
= LOWORD(Msg
->lParam
);
259 pt
.y
= HIWORD(Msg
->lParam
);
262 MapWindowPoints(NULL
, skw
->hWnd
, &pt
, 1);
275 * The standard win32 window procedure that handles win32 messages delivered from ReactOS
277 * @param hWnd Handle of the window
278 * @param msg Specifies the type of the message
279 * @param wParam Additional data to the message
280 * @param lParam Additional data to the message
282 * @return Depends on the message type
285 IntDefaultWin32Proc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
289 if (msg
== WM_NCCREATE
)
292 * Save the pointer to the structure so we can access it later when
293 * dispatching the Win32 messages so we know which sky window it is
294 * and dispatch the right messages.
296 skw
= (PSKY_WINDOW
)((LPCREATESTRUCTW
)lParam
)->lpCreateParams
;
297 SetWindowLongPtr(hWnd
, GWL_USERDATA
, (ULONG_PTR
)skw
);
301 skw
= (PSKY_WINDOW
)GetWindowLongPtr(hWnd
, GWL_USERDATA
);
303 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
309 IntDispatchMsg(&skw
->Window
, MSG_DESTROY
, 0, 0);
315 /* FIXME: Find a more general solution! */
316 /* We can get there for message sent by SendMessage. */
322 BeginPaint(hWnd
, &ps
);
323 srect
.x1
= ps
.rcPaint
.left
;
324 srect
.y1
= ps
.rcPaint
.top
;
325 srect
.x2
= ps
.rcPaint
.right
;
326 srect
.y2
= ps
.rcPaint
.bottom
;
327 IntDispatchMsgRect(&skw
->Window
, MSG_GUI_REDRAW
, 0, 0, &srect
);
334 IntDispatchMsg(&skw
->Window
, MSG_COMMAND
, LOWORD(wParam
), 0);
338 return 1; /* don't handle this message */
341 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
346 * Registers a Win32 window class for all Sky windows
348 * @return Returns the atom of the class registered.
351 IntRegisterClass(void)
355 wc
.lpszClassName
= L
"ROSkyWindow";
356 wc
.lpfnWndProc
= IntDefaultWin32Proc
;
357 wc
.style
= CS_VREDRAW
| CS_HREDRAW
;
358 wc
.hInstance
= GetModuleHandleW(NULL
);
359 wc
.hIcon
= LoadIcon(NULL
, (LPCTSTR
)IDI_APPLICATION
);
360 wc
.hCursor
= LoadCursor(NULL
, (LPCTSTR
)IDC_ARROW
);
361 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
362 wc
.lpszMenuName
= NULL
;
366 return RegisterClassW(&wc
);
374 GI_create_app(app_para
*p
)
377 ULONG Style
, ExStyle
;
378 WCHAR WindowName
[sizeof(p
->cpName
) / sizeof(p
->cpName
[0])];
381 DBG("GI_create_app(0x%x)\n", p
);
384 if(!SkyClassRegistered
)
386 SkyClassAtom
= IntRegisterClass();
387 SkyClassRegistered
= SkyClassAtom
!= 0;
389 if(!SkyClassRegistered
)
391 DBG("Unable to register the ROSkyWindow class\n");
397 skw
= (PSKY_WINDOW
)HeapAlloc(GetProcessHeap(),
402 DBG("Not enough memory to allocate a SKY_WINDOW structure!\n");
406 /* Convert the Sky window style to a Win32 window style */
407 Style
= IntMapWindowStyle(p
->ulStyle
, &ExStyle
);
409 /* convert the window caption to unicode */
410 MultiByteToWideChar(CP_UTF8
, 0, (char*)p
->cpName
, -1, WindowName
,
411 sizeof(WindowName
) / sizeof(WindowName
[0]));
413 skw
->Window
.win_func
= p
->win_func
;
414 /* FIXME - fill the window structure */
417 * We must convert the client rect passed in to the window rect expected
418 * by CreateWindowExW.
422 ClientRect
.right
= 0 + p
->ulWidth
;
423 ClientRect
.bottom
= 0 + p
->ulHeight
;
424 AdjustWindowRectEx(&ClientRect
, Style
, p
->ulStyle
& WF_HAS_MENU
, ExStyle
);
426 DBG("Menu: %x\n", p
->pMenu
? ((PSKY_MENU
)p
->pMenu
)->hMenu
: NULL
);
428 /* create the Win32 window */
429 skw
->hWnd
= CreateWindowExW(ExStyle
,
435 ClientRect
.right
- ClientRect
.left
,
436 ClientRect
.bottom
- ClientRect
.top
,
438 p
->pMenu
? ((PSKY_MENU
)p
->pMenu
)->hMenu
: NULL
,
439 GetModuleHandleW(NULL
),
442 if(skw
->hWnd
== NULL
)
444 DBG("CreateWindow() failed!\n");
445 HeapFree(GetProcessHeap(), 0, skw
);
449 DBG("Created Win32 window: 0x%x\n", skw
->hWnd
);
458 GI_destroy_window(s_window
*win
)
460 PSKY_WINDOW skw
= (PSKY_WINDOW
)win
;
462 DBG("GI_destroy_window(0x%x)\n", win
);
463 DestroyWindow(skw
->hWnd
);
464 HeapFree(GetProcessHeap(), 0, skw
);
474 GI_wait_message(s_gi_msg
*m
,
478 BOOL Ret
, SkyMessage
;
482 DBG("GI_wait_message(0x%x, 0x%x)\n", m
, w
);
484 hwndFilter
= (w
!= NULL
? ((PSKY_WINDOW
)w
)->hWnd
: NULL
);
487 Ret
= GetMessage(&Msg
, hwndFilter
, 0, 0);
489 /* loop until we found a message that a sky app would handle, too */
490 RtlZeroMemory(m
, sizeof(s_gi_msg
));
492 if(Msg
.hwnd
!= NULL
&& (msgwnd
= (PSKY_WINDOW
)GetWindowLongPtrW(Msg
.hwnd
, GWL_USERDATA
)))
494 SkyMessage
= IntIsSkyMessage(msgwnd
, &Msg
, m
);
503 /* We're not interested in dispatching a sky message, try again */
504 TranslateMessage(&Msg
);
505 DispatchMessage(&Msg
);
518 GI_dispatch_message(s_window
*win
,
521 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
522 DBG("GI_dispatch_message(0x%x, 0x%x - %d)\n", win
, m
, m
->type
);
523 /* dispatch the SkyOS message to the SkyOS window procedure */
525 return skywnd
->Window
.win_func(win
, m
);
534 GI_ShowApplicationWindow(s_window
*win
)
536 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
537 DBG("GI_ShowApplicationWindow(0x%x)\n", win
);
538 ShowWindow(skywnd
->hWnd
, SW_SHOW
);
547 GI_redraw_window(s_window
*win
)
549 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
550 DBG("GI_redraw_window(0x%x)!\n", win
);
553 RedrawWindow(skywnd
->hWnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_UPDATENOW
);
563 GI_post_quit(s_window
*win
)
565 DBG("GI_post_quit(0x%x)\n", win
);
566 PostMessage(((PSKY_WINDOW
)win
)->hWnd
, WM_QUIT
, 0, 0);
573 sCreateApplication
* __cdecl
574 GI_CreateApplicationStruct(void)
576 sCreateApplication
*app
;
578 app
= (sCreateApplication
*)HeapAlloc(GetProcessHeap(),
580 sizeof(sCreateApplication
));
581 STUB("GI_CreateApplicationStruct() returns 0x%x (allocated structure on the heap)!\n", app
);
591 GI_GetWindowX(s_window
*win
)
594 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
595 if((skywnd
!= NULL
) && GetWindowRect(skywnd
->hWnd
, &rc
))
597 MapWindowPoints(HWND_DESKTOP
, GetParent(skywnd
->hWnd
), (LPPOINT
)&rc
, 2);
598 DBG("GI_GetWindowS(0x%x) returns %d!\n", win
, rc
.left
);
604 DBG("GI_GetWindowS(0x%x) failed!\n", win
);
615 GI_GetWindowY(s_window
*win
)
618 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
619 if((skywnd
!= NULL
) && GetWindowRect(skywnd
->hWnd
, &rc
))
621 MapWindowPoints(HWND_DESKTOP
, GetParent(skywnd
->hWnd
), (LPPOINT
)&rc
, 2);
622 DBG("GI_GetWindowY(0x%x) returns %d!\n", win
, rc
.top
);
628 DBG("GI_GetWindowY(0x%x) failed!\n", win
);
639 GI_GetWindowWidth(s_window
*win
)
642 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
643 if((skywnd
!= NULL
) && GetWindowRect(skywnd
->hWnd
, &rc
))
645 DBG("GI_GetWindowWidth(0x%x) returns %d!\n", win
, (rc
.right
- rc
.left
));
646 return (rc
.right
- rc
.left
);
651 DBG("GI_GetWindowWidth(0x%x) failed!\n", win
);
662 GI_GetWindowHeight(s_window
*win
)
665 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
666 if((skywnd
!= NULL
) && GetWindowRect(skywnd
->hWnd
, &rc
))
668 DBG("GI_GetWindowHeight(0x%x) returns %d!\n", win
, (rc
.bottom
- rc
.top
));
669 return (rc
.bottom
- rc
.top
);
674 DBG("GI_GetWindowHeight(0x%x) failed!\n", win
);
685 GI_GetTopLevelWindow(s_window
*win
)
687 STUB("GI_GetTopLevelWindow(0x%x) returns 0x%x!\n", win
, win
);
696 GI_create_DIB(void *Data
,
701 unsigned int PaletteSize
)
704 BITMAPINFO
*BitmapInfo
;
706 DBG("GI_create_DIB(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
707 Data
, Width
, Height
, Bpp
, Palette
, PaletteSize
);
709 Dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SKY_DIB
));
715 BitmapInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER
) +
716 PaletteSize
* sizeof(RGBQUAD
));
717 if (BitmapInfo
== NULL
)
719 HeapFree(GetProcessHeap(), 0, Dib
);
723 Dib
->Dib
.color
= Bpp
;
724 Dib
->Dib
.width
= Width
;
725 Dib
->Dib
.height
= Height
;
726 Dib
->Dib
.data
= Data
;
727 Dib
->Dib
.palette_size
= PaletteSize
;
728 Dib
->Dib
.palette
= Palette
;
730 BitmapInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
731 BitmapInfo
->bmiHeader
.biWidth
= Width
;
732 BitmapInfo
->bmiHeader
.biHeight
= Height
;
733 BitmapInfo
->bmiHeader
.biPlanes
= 1;
734 BitmapInfo
->bmiHeader
.biBitCount
= Bpp
;
735 BitmapInfo
->bmiHeader
.biCompression
= BI_RGB
;
736 BitmapInfo
->bmiHeader
.biSizeImage
= 0;
737 BitmapInfo
->bmiHeader
.biXPelsPerMeter
= 0;
738 BitmapInfo
->bmiHeader
.biYPelsPerMeter
= 0;
739 BitmapInfo
->bmiHeader
.biClrUsed
= PaletteSize
;
740 BitmapInfo
->bmiHeader
.biClrImportant
= 0;
741 RtlCopyMemory(BitmapInfo
->bmiColors
, Palette
, PaletteSize
* sizeof(RGBQUAD
));
743 Dib
->hBitmap
= CreateDIBSection(NULL
,
749 HeapFree(GetProcessHeap(), 0, BitmapInfo
);
750 if (Dib
->hBitmap
== NULL
)
752 HeapFree(GetProcessHeap(), 0, Dib
);
764 GC_create_connected(unsigned int Type
,
771 DBG("GC_create_connected(0x%x, 0x%x, 0x%x, 0x%x)\n",
772 Type
, Width
, Height
, Win
);
776 DBG("GC_create_connected: no window specified! returned NULL!\n");
780 Gc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SKY_GC
));
786 Gc
->GraphicsContext
.type
= Type
;
787 Gc
->GraphicsContext
.width
= Width
;
788 Gc
->GraphicsContext
.height
= Height
;
793 Gc
->hDC
= CreateCompatibleDC(0);
796 Gc
->GraphicsContext
.hDIB
= (DIB
*)Win
;
797 SelectObject(Gc
->hDC
, ((PSKY_DIB
)Win
)->hBitmap
);
798 ((PSKY_DIB
)Win
)->hAssociateDC
= Gc
->hDC
;
803 Gc
->hDC
= GetDC(((PSKY_WINDOW
)Win
)->hWnd
);
804 Gc
->GraphicsContext
.window
= Win
;
808 DBG("Unknown GC type: %x\n", Type
);
813 HeapFree(GetProcessHeap(), 0, Gc
);
818 SelectObject(Gc
->hDC
, GetStockObject(DC_BRUSH
));
819 SelectObject(Gc
->hDC
, GetStockObject(DC_PEN
));
830 GC_set_fg_color(GC
*Gc
,
835 Gc
->fg_color
= Color
;
836 SetDCPenColor(((PSKY_GC
)Gc
)->hDC
, Color
);
842 DBG("GC_set_fg_color: Gc == NULL!\n");
853 GC_set_bg_color(GC
*Gc
,
858 Gc
->bg_color
= Color
;
859 SetDCBrushColor(((PSKY_GC
)Gc
)->hDC
, Color
);
865 DBG("GC_set_bg_color: Gc == NULL!\n");
876 GC_draw_pixel(GC
*Gc
,
882 SetPixelV(((PSKY_GC
)Gc
)->hDC
, X
, Y
, Gc
->fg_color
);
888 DBG("GC_draw_pixel: Gc == NULL!\n");
899 GC_blit_from_DIB(GC
*Gc
,
906 HBITMAP hOldBitmap
= NULL
;
908 DBG("GC_blit_from_DIB(0x%x, 0x%x, 0x%x, 0x%x)\n", Gc
, Dib
, X
, Y
);
910 if (((PSKY_DIB
)Dib
)->hAssociateDC
== NULL
)
912 hSrcDC
= CreateCompatibleDC(0);
913 hOldBitmap
= SelectObject(hSrcDC
, ((PSKY_DIB
)Dib
)->hBitmap
);
917 hSrcDC
= ((PSKY_DIB
)Dib
)->hAssociateDC
;
920 Result
= BitBlt(((PSKY_GC
)Gc
)->hDC
, X
, Y
, Dib
->width
, Dib
->height
,
921 hSrcDC
, 0, 0, SRCCOPY
);
923 if (((PSKY_DIB
)Dib
)->hAssociateDC
== NULL
)
925 SelectObject(hSrcDC
, hOldBitmap
);
937 GC_draw_rect_fill(GC
*Gc
,
943 DBG("GC_draw_rect_fill(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
944 Gc
, X
, Y
, Width
, Height
);
953 Rect
.right
= X
+ Width
;
954 Rect
.bottom
= Y
+ Height
;
956 hBrush
= CreateSolidBrush(Gc
->bg_color
);
957 FillRect(((PSKY_GC
)Gc
)->hDC
, &Rect
, hBrush
);
958 DeleteObject(hBrush
);
965 DBG("GC_draw_rect_fill: Gc == NULL!\n");
982 DBG("GC_draw_line(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", Gc
, x1
, y1
, x2
, y2
);
985 MoveToEx(((PSKY_GC
)Gc
)->hDC
, x1
, y1
, NULL
);
986 LineTo(((PSKY_GC
)Gc
)->hDC
, x2
, y2
);
992 DBG("GC_draw_line: Gc == NULL!\n");
1005 DBG("GC_destroy(0x%x)\n", Gc
);
1011 DeleteDC(((PSKY_GC
)Gc
)->hDC
);
1014 case GC_TYPE_WINDOW
:
1015 ReleaseDC(((PSKY_WINDOW
)Gc
->window
)->hWnd
, ((PSKY_GC
)Gc
)->hDC
);
1019 DBG("Unknown GC type: %x\n", Gc
->type
);
1021 HeapFree(GetProcessHeap(), 0, Gc
);
1027 DBG("GC_destroy: Gc == NULL!\n");
1037 widget_menu
* __cdecl
1038 GI_create_menu(s_window
*win
)
1042 DBG("GI_create_menu(0x%x)\n", win
);
1044 Menu
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SKY_MENU
));
1050 /* Shouldn't we use CreatePopupMenu in some cases? */
1051 Menu
->hMenu
= CreateMenu();
1052 if (Menu
->hMenu
== NULL
)
1054 HeapFree(GetProcessHeap(), 0, Menu
);
1060 SetMenu(((PSKY_WINDOW
)win
)->hWnd
, Menu
->hMenu
);
1063 return (widget_menu
*)Menu
;
1070 widget_menu_item
* __cdecl
1071 GI_create_menu_item(unsigned char *Text
,
1074 unsigned int Enabled
)
1076 PSKY_MENUITEM MenuItem
;
1079 DBG("GI_create_menu_item(0x%x, 0x%x, 0x%x, 0x%x)\n",
1080 Text
, Id
, Flags
, Enabled
);
1082 TextLength
= MultiByteToWideChar(CP_UTF8
, 0, (char*)Text
, -1, NULL
, 0);
1083 MenuItem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1084 sizeof(SKY_MENUITEM
) + TextLength
* sizeof(WCHAR
));
1085 if (MenuItem
== NULL
)
1090 lstrcpyA((char*)MenuItem
->MenuItem
.text
, (char*)Text
);
1091 MenuItem
->MenuItem
.ID
= Id
;
1092 MenuItem
->MenuItem
.flags
= Flags
;
1093 MenuItem
->MenuItem
.enabled
= Enabled
;
1095 MenuItem
->MenuItemInfo
.cbSize
= sizeof(MENUITEMINFOW
);
1096 MenuItem
->MenuItemInfo
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
;
1097 if (Flags
& MENU_SEPERATOR
)
1098 MenuItem
->MenuItemInfo
.fType
= MF_SEPARATOR
;
1100 MenuItem
->MenuItemInfo
.fType
= MF_STRING
;
1101 MenuItem
->MenuItemInfo
.fState
= Enabled
? MFS_ENABLED
: 0;
1102 MenuItem
->MenuItemInfo
.wID
= Id
;
1103 MenuItem
->MenuItemInfo
.dwTypeData
= (LPWSTR
)(MenuItem
+ 1);
1104 MenuItem
->MenuItemInfo
.cch
= TextLength
;
1105 MultiByteToWideChar(CP_UTF8
, 0, (char*)Text
, TextLength
, (LPWSTR
)(MenuItem
+ 1),
1108 return (widget_menu_item
*)MenuItem
;
1116 GI_add_menu_item(widget_menu
*Menu
,
1117 widget_menu_item
*Item
)
1119 DBG("GI_add_menu_item(0x%x, 0x%x)\n", Menu
, Item
);
1120 InsertMenuItemW(((PSKY_MENU
)Menu
)->hMenu
, -1, TRUE
,
1121 &((PSKY_MENUITEM
)Item
)->MenuItemInfo
);
1130 GI_add_menu_sub(widget_menu
*Menu
,
1131 widget_menu_item
*Item
,
1134 PSKY_MENUITEM MenuItem
= (PSKY_MENUITEM
)Item
;
1136 DBG("GI_add_menu_sub(0x%x, 0x%x, 0x%x)\n", Menu
, Item
, Sub
);
1137 MenuItem
->MenuItemInfo
.fMask
|= MIIM_SUBMENU
;
1138 MenuItem
->MenuItemInfo
.hSubMenu
= ((PSKY_MENU
)Sub
)->hMenu
;
1139 InsertMenuItemW(((PSKY_MENU
)Menu
)->hMenu
, -1, TRUE
,
1140 &MenuItem
->MenuItemInfo
);
1149 GI_messagebox(s_window
*Window
,
1157 ULONG MbFlags
, MbResult
;
1159 DBG("GI_messagebox(0x%x, 0x%x, 0x%x, 0x%x, ...)\n",
1160 Window
, Flags
, Title
, Fmt
);
1162 va_start(ArgList
, Fmt
);
1163 _vsnprintf(Buffer
, sizeof(Buffer
) / sizeof(Buffer
[0]), Fmt
, ArgList
);
1166 if ((Flags
& (WGF_MB_CANCEL
| WGF_MB_YESNO
)) ==
1167 (WGF_MB_CANCEL
| WGF_MB_YESNO
))
1168 MbFlags
= MB_YESNOCANCEL
;
1169 else if (Flags
& WGF_MB_YESNO
)
1171 else /* if (Flags & WGF_MB_OK) */
1173 MbFlags
|= (Flags
& WGF_MB_ICON_INFO
) ? MB_ICONASTERISK
: 0;
1174 MbFlags
|= (Flags
& WGF_MB_ICON_ASK
) ? MB_ICONQUESTION
: 0;
1175 MbFlags
|= (Flags
& WGF_MB_ICON_STOP
) ? MB_ICONERROR
: 0;
1177 MbResult
= MessageBoxA(Window
? ((PSKY_WINDOW
)Window
)->hWnd
: NULL
,
1178 Buffer
, Title
, MbFlags
);
1182 case IDOK
: return ID_OK
;
1183 case IDYES
: return ID_YES
;
1184 case IDNO
: return ID_NO
;
1185 case IDCANCEL
: return ID_CANCEL
;
1196 GI_EnableMouseTracking(s_window
*win
)
1198 DBG("GI_EnableMouseTracking(0x%x)!\n", win
);
1201 ((PSKY_WINDOW
)win
)->MouseInput
= TRUE
;
1207 DBG("GI_EnableMouseTracking: win == NULL!\n");