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
19 /* $Id: libskygi.c,v 1.9 2004/08/14 01:03:38 weiden Exp $
21 * PROJECT: SkyOS GI library
22 * FILE: lib/libskygi/libskygi.c
23 * PURPOSE: SkyOS GI library
30 #include <rosky/rosky.h>
38 } SKY_WINDOW
, *PSKY_WINDOW
;
44 } SKY_MENU
, *PSKY_MENU
;
48 widget_menu_item MenuItem
;
49 MENUITEMINFOW MenuItemInfo
;
50 } SKY_MENUITEM
, *PSKY_MENUITEM
;
65 static ATOM SkyClassAtom
;
66 static BOOL SkyClassRegistered
= FALSE
;
69 * Map a SkyOS window style to Windows one.
71 * @param SkyStyle SkyOS window style (WF_* flags).
72 * @param ExStyle Contains Windows extended window style on exit.
74 * @return Windows window style (WS_* flags).
77 * WF_MODAL, WF_HAS_MENU, WF_HAS_STATUSBAR, WF_FREEFORM, WF_FOCUSABLE,
78 * WF_USER, WF_DESKTOP, WF_NOT_MOVEABLE, WF_NO_BUTTONS, WF_TRANSPARENT,
79 * WF_NO_INITIAL_DRAW, WF_USE_BACKGROUND, WF_DONT_EREASE_BACKGROUND,
83 IntMapWindowStyle(ULONG SkyStyle
, ULONG
*ExStyle
)
87 Style
= (SkyStyle
& WF_HIDE
) ? 0 : WS_VISIBLE
;
88 Style
|= (SkyStyle
& WF_NO_TITLE
) ? 0 : WS_CAPTION
;
89 Style
|= (SkyStyle
& WF_NOT_SIZEABLE
) ? WS_THICKFRAME
: 0;
90 Style
|= (SkyStyle
& WF_POPUP
) ? WS_POPUP
: 0;
91 Style
|= (SkyStyle
& WF_NO_BUTTONS
) ? 0 :
92 ((SkyStyle
& WF_NOT_SIZEABLE
) ? 0 : WS_MAXIMIZEBOX
) |
93 WS_MINIMIZEBOX
| WS_SYSMENU
;
94 *ExStyle
= (SkyStyle
& WF_SMALL_TITLE
) ? WS_EX_TOOLWINDOW
: 0;
101 * Dispatch a Sky Message to the appropriate window callback
103 * @param win Specifies the destination window
104 * @param type The type of the message (see MSG_ constants)
105 * @param para1 Additional parameter 1
106 * @param para2 Additional parameter 2
108 * @return Returns the return value of the window callback function
111 IntDispatchMsg(s_window
*win
, unsigned int type
, unsigned int para1
, unsigned int para2
)
116 /* fill the members of the struct */
121 msg
.next
= NULL
; /* ??? */
122 msg
.prev
= NULL
; /* ??? */
124 msg
.timestamp
= (unsigned long long)GetTickCount() * 1000LL;
126 DBG("Dispatching window (0x%x) message type %d\n", win
, type
);
127 Ret
= win
->win_func(win
, &msg
);
128 DBG("Dispatched window (0x%x) message type %d, returned 0x%x\n", win
, type
, Ret
);
134 * Dispatch a Sky Message with a update rect to the appropriate window callback
136 * @param win Specifies the destination window
137 * @param type The type of the message (see MSG_ constants)
138 * @param para1 Additional parameter 1
139 * @param para2 Additional parameter 2
140 * @param rect Rectangle of the window to be repainted
142 * @return Returns the return value of the window callback function
145 IntDispatchMsgRect(s_window
*win
, unsigned int type
, unsigned int para1
, unsigned int para2
, s_region
*rect
)
150 /* fill the members of the struct */
155 msg
.next
= NULL
; /* ??? */
156 msg
.prev
= NULL
; /* ??? */
159 msg
.timestamp
= (unsigned long long)GetTickCount() * 1000LL;
161 DBG("Dispatching window (0x%x) message type %d\n", win
, type
);
162 Ret
= win
->win_func(win
, &msg
);
163 DBG("Dispatched window (0x%x) message type %d, returned 0x%x\n", win
, type
, Ret
);
169 * Determines whether a win32 message should cause a Sky message to be dispatched
171 * @param skw Specifies the destination window
172 * @param Msg Contains the win32 message
173 * @param smsg Address to the sky message structure that will be filled in with
174 * appropriate information in case a sky message should be dispatched
176 * @return Returns TRUE if a Sky message should be dispatched
179 IntIsSkyMessage(PSKY_WINDOW skw
, MSG
*Msg
, s_gi_msg
*smsg
)
186 smsg
->type
= MSG_DESTROY
;
196 if(GetUpdateRect(skw
->hWnd
, &rc
, FALSE
))
198 BeginPaint(skw
->hWnd
, &ps
);
199 EndPaint(skw
->hWnd
, &ps
);
201 smsg
->type
= MSG_GUI_REDRAW
;
205 smsg
->rect
.x1
= rc
.left
;
206 smsg
->rect
.y1
= rc
.top
;
207 smsg
->rect
.x2
= rc
.right
;
208 smsg
->rect
.y2
= rc
.bottom
;
216 smsg
->type
= MSG_QUIT
;
228 switch (Msg
->message
)
230 case WM_LBUTTONDOWN
: smsg
->type
= MSG_MOUSE_BUT1_PRESSED
; break;
231 case WM_LBUTTONUP
: smsg
->type
= MSG_MOUSE_BUT1_RELEASED
; break;
232 case WM_RBUTTONDOWN
: smsg
->type
= MSG_MOUSE_BUT2_PRESSED
; break;
233 case WM_RBUTTONUP
: smsg
->type
= MSG_MOUSE_BUT2_RELEASED
; break;
236 pt
.x
= LOWORD(Msg
->lParam
);
237 pt
.y
= HIWORD(Msg
->lParam
);
240 MapWindowPoints(NULL
, skw
->hWnd
, &pt
, 1);
248 smsg
->type
= MSG_COMMAND
;
249 smsg
->para1
= LOWORD(Msg
->wParam
);
258 * The standard win32 window procedure that handles win32 messages delivered from ReactOS
260 * @param hWnd Handle of the window
261 * @param msg Specifies the type of the message
262 * @param wParam Additional data to the message
263 * @param lParam Additional data to the message
265 * @return Depends on the message type
268 IntDefaultWin32Proc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
272 if (msg
== WM_NCCREATE
)
275 * Save the pointer to the structure so we can access it later when
276 * dispatching the Win32 messages so we know which sky window it is
277 * and dispatch the right messages.
279 skw
= (PSKY_WINDOW
)((LPCREATESTRUCTW
)lParam
)->lpCreateParams
;
280 SetWindowLongPtr(hWnd
, GWL_USERDATA
, (ULONG_PTR
)skw
);
284 skw
= (PSKY_WINDOW
)GetWindowLongPtr(hWnd
, GWL_USERDATA
);
286 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
292 IntDispatchMsg(&skw
->Window
, MSG_DESTROY
, 0, 0);
298 /* FIXME: Find a more general solution! */
299 /* We can get there for message sent by SendMessage. */
305 BeginPaint(hWnd
, &ps
);
306 srect
.x1
= ps
.rcPaint
.left
;
307 srect
.y1
= ps
.rcPaint
.top
;
308 srect
.x2
= ps
.rcPaint
.right
;
309 srect
.y2
= ps
.rcPaint
.bottom
;
310 IntDispatchMsgRect(&skw
->Window
, MSG_GUI_REDRAW
, 0, 0, &srect
);
317 IntDispatchMsg(&skw
->Window
, MSG_COMMAND
, LOWORD(wParam
), 0);
321 return 1; /* don't handle this message */
324 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
329 * Registers a Win32 window class for all Sky windows
331 * @return Returns the atom of the class registered.
334 IntRegisterClass(void)
338 wc
.lpszClassName
= L
"ROSkyWindow";
339 wc
.lpfnWndProc
= IntDefaultWin32Proc
;
340 wc
.style
= CS_VREDRAW
| CS_HREDRAW
;
341 wc
.hInstance
= GetModuleHandleW(NULL
);
342 wc
.hIcon
= LoadIcon(NULL
, (LPCTSTR
)IDI_APPLICATION
);
343 wc
.hCursor
= LoadCursor(NULL
, (LPCTSTR
)IDC_ARROW
);
344 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
345 wc
.lpszMenuName
= NULL
;
349 return RegisterClassW(&wc
);
357 GI_create_app(app_para
*p
)
360 ULONG Style
, ExStyle
;
361 WCHAR WindowName
[sizeof(p
->cpName
) / sizeof(p
->cpName
[0])];
364 DBG("GI_create_app(0x%x)\n", p
);
367 if(!SkyClassRegistered
)
369 SkyClassAtom
= IntRegisterClass();
370 SkyClassRegistered
= SkyClassAtom
!= 0;
372 if(!SkyClassRegistered
)
374 DBG("Unable to register the ROSkyWindow class\n");
380 skw
= (PSKY_WINDOW
)HeapAlloc(GetProcessHeap(),
385 DBG("Not enough memory to allocate a SKY_WINDOW structure!\n");
389 /* Convert the Sky window style to a Win32 window style */
390 Style
= IntMapWindowStyle(p
->ulStyle
, &ExStyle
);
392 /* convert the window caption to unicode */
393 MultiByteToWideChar(CP_UTF8
, 0, p
->cpName
, -1, WindowName
,
394 sizeof(WindowName
) / sizeof(WindowName
[0]));
396 skw
->Window
.win_func
= p
->win_func
;
397 /* FIXME - fill the window structure */
400 * We must convert the client rect passed in to the window rect expected
401 * by CreateWindowExW.
405 ClientRect
.right
= 0 + p
->ulWidth
;
406 ClientRect
.bottom
= 0 + p
->ulHeight
;
407 AdjustWindowRectEx(&ClientRect
, Style
, p
->ulStyle
& WF_HAS_MENU
, ExStyle
);
409 DBG("Menu: %x\n", p
->pMenu
? ((PSKY_MENU
)p
->pMenu
)->hMenu
: NULL
);
411 /* create the Win32 window */
412 skw
->hWnd
= CreateWindowExW(ExStyle
,
418 ClientRect
.right
- ClientRect
.left
,
419 ClientRect
.bottom
- ClientRect
.top
,
421 p
->pMenu
? ((PSKY_MENU
)p
->pMenu
)->hMenu
: NULL
,
422 GetModuleHandleW(NULL
),
425 if(skw
->hWnd
== NULL
)
427 DBG("CreateWindow() failed!\n");
428 HeapFree(GetProcessHeap(), 0, skw
);
432 DBG("Created Win32 window: 0x%x\n", skw
->hWnd
);
441 GI_destroy_window(s_window
*win
)
443 PSKY_WINDOW skw
= (PSKY_WINDOW
)win
;
445 DBG("GI_destroy_window(0x%x)\n", win
);
446 DestroyWindow(skw
->hWnd
);
447 HeapFree(GetProcessHeap(), 0, skw
);
457 GI_wait_message(s_gi_msg
*m
,
461 BOOL Ret
, SkyMessage
;
465 DBG("GI_wait_message(0x%x, 0x%x)\n", m
, w
);
467 hwndFilter
= (w
!= NULL
? ((PSKY_WINDOW
)w
)->hWnd
: NULL
);
470 Ret
= GetMessage(&Msg
, hwndFilter
, 0, 0);
472 /* loop until we found a message that a sky app would handle, too */
473 RtlZeroMemory(m
, sizeof(s_gi_msg
));
475 if(Msg
.hwnd
!= NULL
&& (msgwnd
= (PSKY_WINDOW
)GetWindowLongW(Msg
.hwnd
, GWL_USERDATA
)))
477 SkyMessage
= IntIsSkyMessage(msgwnd
, &Msg
, m
);
486 /* We're not interested in dispatching a sky message, try again */
487 TranslateMessage(&Msg
);
488 DispatchMessage(&Msg
);
501 GI_dispatch_message(s_window
*win
,
504 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
505 DBG("GI_dispatch_message(0x%x, 0x%x - %d)\n", win
, m
, m
->type
);
506 /* dispatch the SkyOS message to the SkyOS window procedure */
508 return skywnd
->Window
.win_func(win
, m
);
517 GI_ShowApplicationWindow(s_window
*win
)
519 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
520 DBG("GI_ShowApplicationWindow(0x%x)\n", win
);
521 ShowWindow(skywnd
->hWnd
, SW_SHOW
);
530 GI_redraw_window(s_window
*win
)
532 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
533 DBG("GI_redraw_window(0x%x)!\n", win
);
536 RedrawWindow(skywnd
->hWnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_UPDATENOW
);
546 GI_post_quit(s_window
*win
)
548 DBG("GI_post_quit(0x%x)\n", win
);
549 PostMessage(((PSKY_WINDOW
)win
)->hWnd
, WM_QUIT
, 0, 0);
556 sCreateApplication
* __cdecl
557 GI_CreateApplicationStruct(void)
559 sCreateApplication
*app
;
561 app
= (sCreateApplication
*)HeapAlloc(GetProcessHeap(),
563 sizeof(sCreateApplication
));
564 STUB("GI_CreateApplicationStruct() returns 0x%x (allocated structure on the heap)!\n", app
);
574 GI_GetWindowX(s_window
*win
)
577 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
578 if((skywnd
!= NULL
) && GetWindowRect(skywnd
->hWnd
, &rc
))
580 MapWindowPoints(HWND_DESKTOP
, GetParent(skywnd
->hWnd
), (LPPOINT
)&rc
, 2);
581 DBG("GI_GetWindowS(0x%x) returns %d!\n", win
, rc
.left
);
587 DBG("GI_GetWindowS(0x%x) failed!\n", win
);
598 GI_GetWindowY(s_window
*win
)
601 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
602 if((skywnd
!= NULL
) && GetWindowRect(skywnd
->hWnd
, &rc
))
604 MapWindowPoints(HWND_DESKTOP
, GetParent(skywnd
->hWnd
), (LPPOINT
)&rc
, 2);
605 DBG("GI_GetWindowY(0x%x) returns %d!\n", win
, rc
.top
);
611 DBG("GI_GetWindowY(0x%x) failed!\n", win
);
622 GI_GetWindowWidth(s_window
*win
)
625 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
626 if((skywnd
!= NULL
) && GetWindowRect(skywnd
->hWnd
, &rc
))
628 DBG("GI_GetWindowWidth(0x%x) returns %d!\n", win
, (rc
.right
- rc
.left
));
629 return (rc
.right
- rc
.left
);
634 DBG("GI_GetWindowWidth(0x%x) failed!\n", win
);
645 GI_GetWindowHeight(s_window
*win
)
648 PSKY_WINDOW skywnd
= (PSKY_WINDOW
)win
;
649 if((skywnd
!= NULL
) && GetWindowRect(skywnd
->hWnd
, &rc
))
651 DBG("GI_GetWindowHeight(0x%x) returns %d!\n", win
, (rc
.bottom
- rc
.top
));
652 return (rc
.bottom
- rc
.top
);
657 DBG("GI_GetWindowHeight(0x%x) failed!\n", win
);
668 GI_GetTopLevelWindow(s_window
*win
)
670 STUB("GI_GetTopLevelWindow(0x%x) returns 0x%x!\n", win
, win
);
679 GI_create_DIB(void *Data
,
684 unsigned int PaletteSize
)
687 BITMAPINFO
*BitmapInfo
;
689 DBG("GI_create_DIB(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
690 Data
, Width
, Height
, Bpp
, Palette
, PaletteSize
);
692 Dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SKY_DIB
));
698 BitmapInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER
) +
699 PaletteSize
* sizeof(RGBQUAD
));
700 if (BitmapInfo
== NULL
)
702 HeapFree(GetProcessHeap(), 0, Dib
);
706 Dib
->Dib
.color
= Bpp
;
707 Dib
->Dib
.width
= Width
;
708 Dib
->Dib
.height
= Height
;
709 Dib
->Dib
.data
= Data
;
710 Dib
->Dib
.palette_size
= PaletteSize
;
711 Dib
->Dib
.palette
= Palette
;
713 BitmapInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
714 BitmapInfo
->bmiHeader
.biWidth
= Width
;
715 BitmapInfo
->bmiHeader
.biHeight
= Height
;
716 BitmapInfo
->bmiHeader
.biPlanes
= 1;
717 BitmapInfo
->bmiHeader
.biBitCount
= Bpp
;
718 BitmapInfo
->bmiHeader
.biCompression
= BI_RGB
;
719 BitmapInfo
->bmiHeader
.biSizeImage
= 0;
720 BitmapInfo
->bmiHeader
.biXPelsPerMeter
= 0;
721 BitmapInfo
->bmiHeader
.biYPelsPerMeter
= 0;
722 BitmapInfo
->bmiHeader
.biClrUsed
= PaletteSize
;
723 BitmapInfo
->bmiHeader
.biClrImportant
= 0;
724 RtlCopyMemory(BitmapInfo
->bmiColors
, Palette
, PaletteSize
* sizeof(RGBQUAD
));
726 Dib
->hBitmap
= CreateDIBSection(NULL
,
732 HeapFree(GetProcessHeap(), 0, BitmapInfo
);
733 if (Dib
->hBitmap
== NULL
)
735 HeapFree(GetProcessHeap(), 0, Dib
);
747 GC_create_connected(unsigned int Type
,
754 DBG("GC_create_connected(0x%x, 0x%x, 0x%x, 0x%x)\n",
755 Type
, Width
, Height
, Win
);
759 DBG("GC_create_connected: no window specified! returned NULL!\n");
763 Gc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SKY_GC
));
769 Gc
->GraphicsContext
.type
= Type
;
770 Gc
->GraphicsContext
.width
= Width
;
771 Gc
->GraphicsContext
.height
= Height
;
776 Gc
->hDC
= CreateCompatibleDC(0);
779 Gc
->GraphicsContext
.hDIB
= (DIB
*)Win
;
780 SelectObject(Gc
->hDC
, ((PSKY_DIB
)Win
)->hBitmap
);
781 ((PSKY_DIB
)Win
)->hAssociateDC
= Gc
->hDC
;
786 Gc
->hDC
= GetDC(((PSKY_WINDOW
)Win
)->hWnd
);
787 Gc
->GraphicsContext
.window
= Win
;
791 DBG("Unknown GC type: %x\n", Type
);
796 HeapFree(GetProcessHeap(), 0, Gc
);
801 SelectObject(Gc
->hDC
, GetStockObject(DC_BRUSH
));
802 SelectObject(Gc
->hDC
, GetStockObject(DC_PEN
));
813 GC_set_fg_color(GC
*Gc
,
818 Gc
->fg_color
= Color
;
819 SetDCPenColor(((PSKY_GC
)Gc
)->hDC
, Color
);
825 DBG("GC_set_fg_color: Gc == NULL!\n");
836 GC_set_bg_color(GC
*Gc
,
841 Gc
->bg_color
= Color
;
842 SetDCBrushColor(((PSKY_GC
)Gc
)->hDC
, Color
);
848 DBG("GC_set_bg_color: Gc == NULL!\n");
859 GC_draw_pixel(GC
*Gc
,
865 SetPixelV(((PSKY_GC
)Gc
)->hDC
, X
, Y
, Gc
->fg_color
);
871 DBG("GC_draw_pixel: Gc == NULL!\n");
882 GC_blit_from_DIB(GC
*Gc
,
891 DBG("GC_blit_from_DIB(0x%x, 0x%x, 0x%x, 0x%x)\n", Gc
, Dib
, X
, Y
);
893 if (((PSKY_DIB
)Dib
)->hAssociateDC
== NULL
)
895 hSrcDC
= CreateCompatibleDC(0);
896 hOldBitmap
= SelectObject(hSrcDC
, ((PSKY_DIB
)Dib
)->hBitmap
);
900 hSrcDC
= ((PSKY_DIB
)Dib
)->hAssociateDC
;
903 Result
= BitBlt(((PSKY_GC
)Gc
)->hDC
, X
, Y
, Dib
->width
, Dib
->height
,
904 hSrcDC
, 0, 0, SRCCOPY
);
906 if (((PSKY_DIB
)Dib
)->hAssociateDC
== NULL
)
908 SelectObject(hSrcDC
, hOldBitmap
);
920 GC_draw_rect_fill(GC
*Gc
,
926 DBG("GC_draw_rect_fill(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
927 Gc
, X
, Y
, Width
, Height
);
936 Rect
.right
= X
+ Width
;
937 Rect
.bottom
= Y
+ Height
;
939 hBrush
= CreateSolidBrush(Gc
->bg_color
);
940 FillRect(((PSKY_GC
)Gc
)->hDC
, &Rect
, hBrush
);
941 DeleteObject(hBrush
);
948 DBG("GC_draw_rect_fill: Gc == NULL!\n");
965 DBG("GC_draw_line(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", Gc
, x1
, y1
, x2
, y2
);
968 MoveToEx(((PSKY_GC
)Gc
)->hDC
, x1
, y1
, NULL
);
969 LineTo(((PSKY_GC
)Gc
)->hDC
, x2
, y2
);
975 DBG("GC_draw_line: Gc == NULL!\n");
988 DBG("GC_destroy(0x%x)\n", Gc
);
994 DeleteDC(((PSKY_GC
)Gc
)->hDC
);
998 ReleaseDC(((PSKY_WINDOW
)Gc
->window
)->hWnd
, ((PSKY_GC
)Gc
)->hDC
);
1002 DBG("Unknown GC type: %x\n", Gc
->type
);
1004 HeapFree(GetProcessHeap(), 0, Gc
);
1010 DBG("GC_destroy: Gc == NULL!\n");
1020 widget_menu
* __cdecl
1021 GI_create_menu(s_window
*win
)
1025 DBG("GI_create_menu(0x%x)\n", win
);
1027 Menu
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SKY_MENU
));
1033 /* Shouldn't we use CreatePopupMenu in some cases? */
1034 Menu
->hMenu
= CreateMenu();
1035 if (Menu
->hMenu
== NULL
)
1037 HeapFree(GetProcessHeap(), 0, Menu
);
1043 SetMenu(((PSKY_WINDOW
)win
)->hWnd
, Menu
->hMenu
);
1046 return (widget_menu
*)Menu
;
1053 widget_menu_item
* __cdecl
1054 GI_create_menu_item(unsigned char *Text
,
1057 unsigned int Enabled
)
1059 PSKY_MENUITEM MenuItem
;
1062 DBG("GI_create_menu_item(0x%x, 0x%x, 0x%x, 0x%x)\n",
1063 Text
, Id
, Flags
, Enabled
);
1065 TextLength
= MultiByteToWideChar(CP_UTF8
, 0, Text
, -1, NULL
, 0);
1066 MenuItem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1067 sizeof(SKY_MENUITEM
) + TextLength
* sizeof(WCHAR
));
1068 if (MenuItem
== NULL
)
1073 lstrcpyA(MenuItem
->MenuItem
.text
, Text
);
1074 MenuItem
->MenuItem
.ID
= Id
;
1075 MenuItem
->MenuItem
.flags
= Flags
;
1076 MenuItem
->MenuItem
.enabled
= Enabled
;
1078 MenuItem
->MenuItemInfo
.cbSize
= sizeof(MENUITEMINFOW
);
1079 MenuItem
->MenuItemInfo
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
;
1080 if (Flags
& MENU_SEPERATOR
)
1081 MenuItem
->MenuItemInfo
.fType
= MF_SEPARATOR
;
1083 MenuItem
->MenuItemInfo
.fType
= MF_STRING
;
1084 MenuItem
->MenuItemInfo
.fState
= Enabled
? MFS_ENABLED
: 0;
1085 MenuItem
->MenuItemInfo
.wID
= Id
;
1086 MenuItem
->MenuItemInfo
.dwTypeData
= (LPWSTR
)(MenuItem
+ 1);
1087 MenuItem
->MenuItemInfo
.cch
= TextLength
;
1088 MultiByteToWideChar(CP_UTF8
, 0, Text
, TextLength
, (LPWSTR
)(MenuItem
+ 1),
1091 return (widget_menu_item
*)MenuItem
;
1099 GI_add_menu_item(widget_menu
*Menu
,
1100 widget_menu_item
*Item
)
1102 DBG("GI_add_menu_item(0x%x, 0x%x)\n", Menu
, Item
);
1103 InsertMenuItemW(((PSKY_MENU
)Menu
)->hMenu
, -1, TRUE
,
1104 &((PSKY_MENUITEM
)Item
)->MenuItemInfo
);
1113 GI_add_menu_sub(widget_menu
*Menu
,
1114 widget_menu_item
*Item
,
1117 PSKY_MENUITEM MenuItem
= (PSKY_MENUITEM
)Item
;
1119 DBG("GI_add_menu_sub(0x%x, 0x%x, 0x%x)\n", Menu
, Item
, Sub
);
1120 MenuItem
->MenuItemInfo
.fMask
|= MIIM_SUBMENU
;
1121 MenuItem
->MenuItemInfo
.hSubMenu
= ((PSKY_MENU
)Sub
)->hMenu
;
1122 InsertMenuItemW(((PSKY_MENU
)Menu
)->hMenu
, -1, TRUE
,
1123 &MenuItem
->MenuItemInfo
);
1132 GI_messagebox(s_window
*win
,
1141 DBG("GI_messagebox(0x%x, 0x%x, 0x%x, 0x%x, ...)\n",
1142 win
, Flags
, Title
, Fmt
);
1144 va_start(ArgList
, Fmt
);
1145 _vsnprintf(Buffer
, sizeof(Buffer
) / sizeof(Buffer
[0]), Fmt
, ArgList
);
1148 /** @todo Convert flags and fix return value! */
1149 MessageBoxA(win
? ((PSKY_WINDOW
)win
)->hWnd
: NULL
,
1150 Buffer
, Title
, MB_OK
);