|
From: <kr_...@us...> - 2003-04-23 21:49:30
|
Update of /cvsroot/htoolkit/port/src/cbits/Win32
In directory sc8-pr-cvs1:/tmp/cvs-serv26873/port/src/cbits/Win32
Modified Files:
Frame.c Menu.c Util.c Window.c
Added Files:
MenuHandlesMap.c MenuHandlesMap.h
Log Message:
Complete implementation for Menu with both GTK and Win32.
Supported:
- command menu items with bitmaps
- checked menu items
- radio menu items
- sepparators
- sub menus
--- NEW FILE: MenuHandlesMap.c ---
#include "MenuHandlesMap.h"
#include "Window.h"
#include "Internals.h"
#include "Handlers_stub.h"
#include <stdlib.h>
MenuHandlesMap *newMenuHandlesMap()
{
MenuHandlesMap *pMap;
pMap = (MenuHandlesMap *) malloc(sizeof(MenuHandlesMap));
if (!pMap)
return NULL;
pMap->children = NULL;
pMap->pFreeList = NULL;
pMap->pBlocks = NULL;
pMap->nAccelCount = 0;
pMap->hAccelTable = NULL;
pMap->nMenuID = 0;
memset(pMap->HashTable, 0, sizeof(MenuHandle)*HASH_TABLE_SIZE);
return pMap;
}
void deleteMenuHandlesMap(MenuHandlesMap *pMap)
{
Block *p, *pNext;
pMap->pFreeList = NULL;
p = pMap->pBlocks;
while (p != NULL)
{
pNext = p->pNext;
free(p);
p = pNext;
}
if (pMap->hAccelTable)
DestroyAcceleratorTable(pMap->hAccelTable);
free(pMap);
}
MenuHandle newMenuHandle(MenuHandlesMap *pMap, MenuHandle parent, MENU_TYPE type, int pos)
{
int i;
MenuHandle handle, child, *prev;
unsigned int nHash;
// it doesn't exist, add a new Association
if (pMap->pFreeList == NULL)
{
// add another block
Block *p = (Block *) malloc(sizeof(Block) + HASH_BLOCK_SIZE * sizeof(*handle));
if (!p) return 0;
p->pNext = pMap->pBlocks;
pMap->pBlocks = p; // change head (adds in reverse order for simplicity)
// chain them into free list
handle = (MenuHandle) (p+1);
// free in reverse order to make it easier to debug
handle += HASH_BLOCK_SIZE - 1;
for (i = HASH_BLOCK_SIZE-1; i >= 0; i--, handle--)
{
handle->next = pMap->pFreeList;
pMap->pFreeList = handle;
}
}
handle = pMap->pFreeList;
pMap->pFreeList = pMap->pFreeList->next;
handle->parent = parent;
handle->id = ++pMap->nMenuID;
handle->key = 0;
handle->mods = 0;
handle->bitmap = NULL;
handle->children = NULL;
handle->type = type;
handle->hMenu = NULL;
if (parent)
{
child = parent->children;
prev = &parent->children;
}
else
{
child = pMap->children;
prev = &pMap->children;
}
if (pos < 0)
while (child)
{
prev = &child->sibling;
child = child->sibling;
}
else
while (child && pos > 0)
{
prev = &child->sibling;
child = child->sibling;
pos--;
}
handle->sibling = child;
*prev = handle;
// put into hash table
nHash = (handle->id >> 4) % HASH_TABLE_SIZE;
handle->next = pMap->HashTable[nHash];
pMap->HashTable[nHash] = handle;
return handle;
}
void deleteMenuHandle(MenuHandlesMap *pMap, MenuHandle handle)
{
int nHash;
MenuHandle child, *prev;
while (handle->children)
deleteMenuHandle(pMap, handle->children);
if (handle->parent)
{
prev = &handle->parent->children;
child = handle->parent->children;
}
else
{
prev = &pMap->children;
child = pMap->children;
}
while (child)
{
if (child == handle)
{
*prev = handle->sibling;
break;
}
prev = &child->sibling;
child = child->sibling;
}
nHash = (handle->id >> 4) % HASH_TABLE_SIZE;
prev = &(pMap->HashTable[nHash]);
child = pMap->HashTable[nHash];
while (child)
{
if (child == handle)
{
*prev = handle->next;
break;
}
prev = &child->next;
child = child->next;
}
handle->next = pMap->pFreeList;
pMap->pFreeList = handle;
}
MenuHandle getMenuHandle(MenuHandlesMap *pMap, UINT id)
{
MenuHandle handle;
unsigned int nHash;
nHash = (id >> 4) % HASH_TABLE_SIZE;
for (handle = pMap->HashTable[nHash]; handle != NULL; handle = handle->next)
{
if (handle->id == id)
return handle;
}
return NULL;
}
void updateAccelTable(MenuHandlesMap *pMap, MenuHandle handle, int key, unsigned int mods)
{
if ( handle->key && !key) pMap->nAccelCount--;
if (!handle->key && key) pMap->nAccelCount++;
handle->key = key;
handle->mods = mods;
if (pMap->hAccelTable)
{
DestroyAcceleratorTable(pMap->hAccelTable);
pMap->hAccelTable = NULL;
}
};
HACCEL getAccelTableFromMap(MenuHandlesMap *pMap)
{
int i,k;
MenuHandle handle;
ACCEL *pAccel;
if (pMap->hAccelTable)
return pMap->hAccelTable;
if (pMap->nAccelCount == 0)
return NULL;
pAccel = malloc(sizeof(ACCEL)*pMap->nAccelCount);
if (!pAccel)
return NULL;
for (k = 0, i = 0; k < pMap->nAccelCount; i++)
{
handle = pMap->HashTable[i];
while (handle)
{
pAccel[k].cmd = handle->id;
if (handle->key > 0 && handle->key < 256)
{
pAccel[k].key = handle->key;
pAccel[k].fVirt = 0;
k++;
}
else
if (handle->key > 256 && handle->key < 512)
{
pAccel[k].key = handle->key-256;
pAccel[k].fVirt = FALT;
k++;
}
else
{
pAccel[k].fVirt = (((handle->mods & shiftBIT) ? FSHIFT : 0) |
((handle->mods & ctrlBIT ) ? FCONTROL : 0) |
((handle->mods & altBIT ) ? FALT : 0) | FVIRTKEY);
switch (handle->key)
{
case kbUp: pAccel[k++].key = VK_UP; break;
case kbDown: pAccel[k++].key = VK_DOWN; break;
case kbLeft: pAccel[k++].key = VK_LEFT; break;
case kbRight: pAccel[k++].key = VK_RIGHT; break;
case kbPgUp: pAccel[k++].key = VK_PRIOR; break;
case kbPgDown: pAccel[k++].key = VK_NEXT; break;
case kbEnd: pAccel[k++].key = VK_END; break;
case kbBegin: pAccel[k++].key = VK_HOME; break;
case kbBackSpace:pAccel[k++].key = VK_BACK; break;
case kbDelete: pAccel[k++].key = VK_DELETE; break;
case kbEnter: pAccel[k++].key = VK_RETURN; break;
case kbEscape: pAccel[k++].key = VK_ESCAPE; break;
case kbTab: pAccel[k++].key = VK_TAB; break;
case kbHelp: pAccel[k++].key = VK_HELP; break;
case kbF1: pAccel[k++].key = VK_F1; break;
case kbF2: pAccel[k++].key = VK_F2; break;
case kbF3: pAccel[k++].key = VK_F3; break;
case kbF4: pAccel[k++].key = VK_F4; break;
case kbF5: pAccel[k++].key = VK_F5; break;
case kbF6: pAccel[k++].key = VK_F6; break;
case kbF7: pAccel[k++].key = VK_F7; break;
case kbF8: pAccel[k++].key = VK_F8; break;
case kbF9: pAccel[k++].key = VK_F9; break;
case kbF10: pAccel[k++].key = VK_F10; break;
case kbF11: pAccel[k++].key = VK_F11; break;
case kbF12: pAccel[k++].key = VK_F12; break;
case kbClear: pAccel[k++].key = VK_CLEAR; break;
}
}
handle = handle->next;
}
}
pMap->hAccelTable = CreateAcceleratorTable(pAccel, pMap->nAccelCount);
free(pAccel);
return pMap->hAccelTable;
};
static BOOL getMenuPosEx(MenuHandle firstSibling, MenuHandle handle, int *pos)
{
MenuHandle h;
h = firstSibling;
while (h)
{
if (h == handle)
return TRUE;
if (h->type != MENU_RADIO_GROUP)
*pos += 1;
else
{
if (getMenuPosEx(h->children, handle, pos))
return TRUE;
}
h = h->sibling;
}
return FALSE;
};
int getMenuPos(MenuHandlesMap *pMap, MenuHandle handle)
{
int pos;
MenuHandle parent;
parent = handle->parent;
while (parent && parent->hMenu == NULL)
parent = parent->parent;
pos = 0;
if (!getMenuPosEx(parent ? parent->children : pMap->children, handle, &pos))
return -1;
return pos;
};
int getMenuIndex(MenuHandlesMap *pMap, MenuHandle handle)
{
int index;
MenuHandle child;
index = 0;
child = handle->parent ? handle->parent->children : pMap->children;
while (child)
{
if (child == handle)
break;
index += 1;
child = child->sibling;
}
return index;
};
HMENU getParentHMENU(MenuHandle handle)
{
MenuHandle parent;
parent = handle->parent;
while (parent && parent->hMenu == NULL)
parent = parent->parent;
if (parent == NULL)
return GetMenu(ghWndFrame);
else
return parent->hMenu;
}
int getChildrenCount(MenuHandlesMap *pMap, MenuHandle handle)
{
int count;
MenuHandle child;
count = 0;
child = handle ? handle->children : pMap->children;
while (child != NULL)
{
count++;
child = child->sibling;
}
return count;
}
MenuHandle getNthChild(MenuHandlesMap *pMap, MenuHandle handle, int index)
{
MenuHandle child;
child = handle ? handle->children : pMap->children;
while (child != NULL && index > 0)
{
index--;
child = child->sibling;
}
return child;
}
void notifyHandleForDestroy(MenuHandle handle)
{
MenuHandle child;
child = handle->children;
while (child)
{
notifyHandleForDestroy(child);
child = child->sibling;
}
handleMenuDestroy(handle);
}
void notifyAllHandlesForDestroy(MenuHandlesMap *pMap)
{
MenuHandle child;
child = pMap->children;
while (child)
{
notifyHandleForDestroy(child);
child = child->sibling;
}
}
--- NEW FILE: MenuHandlesMap.h ---
#ifndef MENU_ITEMS_MAP_H
#define MENU_ITEMS_MAP_H
#include "Types.h"
#define HASH_BLOCK_SIZE 10
#define HASH_TABLE_SIZE 17
enum MENU_TYPE
{ MENU_SEPARATOR = 1
, MENU_ITEM = 2
, MENU_POPUP = 4
, MENU_CHECK_ITEM = 8
, MENU_RADIO_GROUP = 16
, MENU_RADIO_ITEM = 32
};
typedef enum MENU_TYPE MENU_TYPE;
struct MenuHandle
{
struct MenuHandle *next;
struct MenuHandle *parent;
struct MenuHandle *children;
struct MenuHandle *sibling;
UINT id;
HMENU hMenu;
int key, mods;
BitmapHandle bitmap;
MENU_TYPE type;
};
typedef struct Block_tag
{
struct Block_tag *pNext;
} Block;
typedef struct
{
struct MenuHandle *children;
Block* pBlocks;
MenuHandle pFreeList;
MenuHandle HashTable[HASH_TABLE_SIZE];
HACCEL hAccelTable;
int nAccelCount;
UINT nMenuID;
} MenuHandlesMap;
MenuHandlesMap *newMenuHandlesMap();
void deleteMenuHandlesMap(MenuHandlesMap *pMap);
MenuHandle newMenuHandle(MenuHandlesMap *pMap, MenuHandle parent, MENU_TYPE type, int pos);
void deleteMenuHandle(MenuHandlesMap *pMap, MenuHandle handle);
MenuHandle getMenuHandle(MenuHandlesMap *pMap, UINT id);
int getMenuPos(MenuHandlesMap *pMap, MenuHandle handle);
int getMenuIndex(MenuHandlesMap *pMap, MenuHandle handle);
void updateAccelTable(MenuHandlesMap *pMap, MenuHandle item, int key, unsigned int mods);
HACCEL getAccelTableFromMap(MenuHandlesMap *pMap);
HMENU getParentHMENU(MenuHandle handle);
int getChildrenCount(MenuHandlesMap *pMap, MenuHandle handle);
MenuHandle getNthChild(MenuHandlesMap *pMap, MenuHandle handle, int index);
void notifyHandleForDestroy(MenuHandle handle);
void notifyAllHandlesForDestroy(MenuHandlesMap *pMap);
#endif
Index: Frame.c
===================================================================
RCS file: /cvsroot/htoolkit/port/src/cbits/Win32/Frame.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** Frame.c 1 Apr 2003 23:54:20 -0000 1.6
--- Frame.c 23 Apr 2003 21:48:53 -0000 1.7
***************
*** 1,11 ****
#include "Types.h"
#include "Window.h"
#include "Internals.h"
#include "Handlers_stub.h"
! #define OSMenuIDEnd 500
LRESULT CALLBACK HFrameSharedFunction(int DocumentInterface, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
FrameData *pData = (FrameData *) GetWindowLong(hWnd,GWL_USERDATA);
--- 1,19 ----
#include "Types.h"
#include "Window.h"
+ #include "MenuHandlesMap.h"
+ #include "Canvas.h"
#include "Internals.h"
#include "Handlers_stub.h"
! #define OSMenuIDEnd 1500
!
! #define Spacing 1
LRESULT CALLBACK HFrameSharedFunction(int DocumentInterface, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
+ int pos, ppos;
+ HMENU hParent;
+ MENUITEMINFO mii;
+ MenuHandle handle;
FrameData *pData = (FrameData *) GetWindowLong(hWnd,GWL_USERDATA);
***************
*** 16,22 ****
--- 24,32 ----
return 0;
case WM_DESTROY:
+ notifyAllHandlesForDestroy(pData->pMenuHandlesMap);
handleProcessDestroy();
DeleteObject(pData->hControlFont);
free(pData->lpszAppName);
+ deleteMenuHandlesMap(pData->pMenuHandlesMap);
free(pData);
PostQuitMessage(0);
***************
*** 59,62 ****
--- 69,73 ----
pData->hControlFont = hControlFont;
pData->lpszAppName = NULL;
+ pData->pMenuHandlesMap = newMenuHandlesMap();
nLen = GetWindowTextLength(hWnd);
***************
*** 85,90 ****
case WM_COMMAND:
if (lParam == 0)
! handleMenuCommand((MenuHandle) (UINT) LOWORD(wParam));
break;
}
--- 96,346 ----
case WM_COMMAND:
if (lParam == 0)
! {
! handle = getMenuHandle(pData->pMenuHandlesMap, (UINT) LOWORD(wParam));
! if (handle)
! {
! hParent = getParentHMENU(handle);
! pos = getMenuPos(pData->pMenuHandlesMap, handle);
!
! mii.cbSize = sizeof(mii);
! mii.fMask = MIIM_STATE;
! GetMenuItemInfo(hParent, pos, TRUE, &mii);
!
! switch (handle->type)
! {
! case MENU_RADIO_ITEM:
! ppos = getMenuPos(pData->pMenuHandlesMap, handle->parent);
! CheckMenuRadioItem(hParent, ppos, ppos+getChildrenCount(pData->pMenuHandlesMap, handle->parent)-1, pos, MF_BYPOSITION);
! break;
! case MENU_CHECK_ITEM:
! CheckMenuItem(hParent, pos, ((mii.fState & MFS_CHECKED) ? MF_UNCHECKED : MF_CHECKED) | MF_BYPOSITION);
! break;
! default:
! }
!
! handleMenuCommand(handle);
! }
! }
! break;
! case WM_MEASUREITEM:
! {
! LPMEASUREITEMSTRUCT lpMIS = (LPMEASUREITEMSTRUCT) lParam;
!
! if (lpMIS->CtlType == ODT_MENU)
! {
! handle = getMenuHandle(pData->pMenuHandlesMap, lpMIS->itemID);
!
! if (handle && handle->bitmap)
! {
! NONCLIENTMETRICS ncm;
! HFONT hFont, hOldFont;
! RECT rc;
! HDC hDC;
! long lDims;
! WORD wCheckWidth, wCheckHeight;
!
! hDC = GetDC(hWnd);
!
! ZeroMemory(&ncm,sizeof(ncm));
! ncm.cbSize = sizeof(ncm);
!
! // Get the menu dimensions
! SystemParametersInfo(SPI_GETNONCLIENTMETRICS,0,(PVOID)&ncm,FALSE);
!
! // Create a font based on menu metrics
! hFont = CreateFontIndirect(&ncm.lfMenuFont);
!
! hOldFont = SelectObject(hDC, hFont);
!
! // Draw out menu item caption - text.
! pos = getMenuPos(pData->pMenuHandlesMap, handle);
! hParent = getParentHMENU(handle);
!
! ZeroMemory(&mii,sizeof(mii));
! mii.cbSize = sizeof(mii);
! mii.fMask = MIIM_STRING;
! mii.fType = MFT_STRING;
! mii.dwTypeData = NULL;
! mii.cch = 0;
! GetMenuItemInfo(hParent, pos, TRUE, &mii);
! mii.cch++;
! mii.dwTypeData = malloc(mii.cch);
!
! if (mii.dwTypeData)
! {
! GetMenuItemInfo(hParent, pos, TRUE, &mii);
!
! DrawText(hDC,mii.dwTypeData,mii.cch,&rc,DT_SINGLELINE|DT_VCENTER|DT_LEFT|DT_CALCRECT|DT_EXPANDTABS);
!
! lDims = GetMenuCheckMarkDimensions();
! wCheckWidth = (WORD)(LOWORD(lDims)+Spacing);
! wCheckHeight = (WORD)(HIWORD(lDims)+Spacing);
!
! wCheckWidth = (WORD)max(handle->bitmap->destsize.cx, wCheckWidth);
! wCheckHeight = (WORD)max(handle->bitmap->destsize.cy, wCheckHeight);
!
! lpMIS->itemWidth = (rc.right-rc.left) + wCheckWidth + (Spacing*2); // Text width
! lpMIS->itemHeight = max((rc.bottom-rc.top),wCheckHeight) + (Spacing*2); // Text Height
! }
!
! free(mii.dwTypeData);
!
! // Clean up resources
! SelectObject(hDC,hOldFont);
! DeleteObject(hFont);
! ReleaseDC(hWnd,hDC);
! }
! }
! }
break;
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) lParam;
+
+ if (lpDIS->CtlType == ODT_MENU)
+ {
+ handle = getMenuHandle(pData->pMenuHandlesMap, lpDIS->itemID);
+
+ if (handle && handle->bitmap)
+ {
+ long lDims;
+ RECT rcFrame, rcBox, rcFill, rc;
+ POINT pt;
+ WORD wCheckWidth, wCheckHeight;
+ WORD wWidth, wHeight;
+ int nIndexDC;
+ HBRUSH hFillBrush;
+ DWORD dwDrawFlags;
+ struct CanvasHandle canvas;
+
+ canvas.hDC = lpDIS->hDC;
+
+ // Check box dimensions
+ lDims = GetMenuCheckMarkDimensions();
+ wCheckWidth = LOWORD(lDims);
+ wCheckHeight = HIWORD(lDims);
+
+ wWidth = max(handle->bitmap->destsize.cx, wCheckWidth) + (Spacing*2);
+ wHeight = max(handle->bitmap->destsize.cy, wCheckHeight) + (Spacing*2);
+
+ rcFrame.left = lpDIS->rcItem.left;
+ rcFrame.top = lpDIS->rcItem.top;
+ rcFrame.right = lpDIS->rcItem.bottom - lpDIS->rcItem.top;
+ rcFrame.bottom= lpDIS->rcItem.top+wHeight;
+
+ rcBox.left = rcFrame.left+1;
+ rcBox.top = rcFrame.top+1;
+ rcBox.right = rcFrame.right-1;
+ rcBox.bottom= rcFrame.bottom-1;
+
+ // Save off context attributes
+ nIndexDC = SaveDC(lpDIS->hDC);
+
+ // create brush for selection state
+ if (lpDIS->itemState & ODS_SELECTED)
+ {
+ hFillBrush = GetSysColorBrush(COLOR_HIGHLIGHT);
+ SetTextColor(lpDIS->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+ }
+ else
+ hFillBrush = CreateSolidBrush(GetBkColor(lpDIS->hDC));
+
+ SetBkMode(lpDIS->hDC,TRANSPARENT);
+
+ // Add some spacing before drawing the text and hi-lite
+ rcFill.left = lpDIS->rcItem.left;
+ rcFill.top = lpDIS->rcItem.top-1;
+ rcFill.right = lpDIS->rcItem.right;
+ rcFill.bottom= lpDIS->rcItem.bottom;
+
+ if ((lpDIS->itemState & ODS_SELECTED) && (lpDIS->itemState & ODS_CHECKED))
+ rcFill.left+=wWidth+Spacing;
+
+ FillRect(lpDIS->hDC, &rcFill, hFillBrush);
+
+ rc = lpDIS->rcItem;
+ rc.left += wWidth+Spacing;
+
+ // Draw out the bitmap associated with the menu item.
+ pt.x = rcFrame.left+(((rcFrame.right-rcFrame.left) - handle->bitmap->destsize.cx)/2);
+ pt.y = rcFrame.top +(((rcFrame.bottom-rcFrame.top) - handle->bitmap->destsize.cy)/2);
+
+ osDrawBitmap(pt.x, pt.y, handle->bitmap, &canvas);
+
+ // Draw bounding frame
+ if (lpDIS->itemState & ODS_SELECTED)
+ DrawEdge(lpDIS->hDC,&rcFrame,BDR_RAISEDINNER,BF_RECT);
+
+ rc.left+=Spacing;
+
+ // Draw out menu item caption - text.
+ pos = getMenuPos(pData->pMenuHandlesMap, handle);
+ hParent = getParentHMENU(handle);
+
+ ZeroMemory(&mii,sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STRING;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = NULL;
+ mii.cch = 0;
+ GetMenuItemInfo(hParent, pos, TRUE, &mii);
+ mii.cch++;
+ mii.dwTypeData = malloc(mii.cch);
+
+ if (mii.dwTypeData)
+ {
+ GetMenuItemInfo(hParent, pos, TRUE, &mii);
+
+ dwDrawFlags = DT_SINGLELINE|DT_VCENTER|DT_LEFT|DT_EXPANDTABS;
+
+ if (lpDIS->itemState & ODS_GRAYED)
+ {
+ // This will give it a disable text look
+ if (!(lpDIS->itemState & ODS_SELECTED))
+ {
+ SetTextColor(lpDIS->hDC, GetSysColor(COLOR_3DHILIGHT));
+ OffsetRect(&rc,1,1);
+ DrawText(lpDIS->hDC,mii.dwTypeData,mii.cch,&rc,dwDrawFlags);
+ OffsetRect(&rc,-1,-1);
+
+ SetTextColor(lpDIS->hDC,GetSysColor(COLOR_GRAYTEXT));
+ DrawText(lpDIS->hDC,mii.dwTypeData,mii.cch,&rc,dwDrawFlags);
+ }
+ else
+ {
+ COLORREF crGray = (GetSysColor(COLOR_GRAYTEXT) + RGB(64,64,64));
+ SetTextColor(lpDIS->hDC,crGray);
+ DrawText(lpDIS->hDC,mii.dwTypeData,mii.cch,&rc,dwDrawFlags);
+ }
+ }
+ else
+ DrawText(lpDIS->hDC,mii.dwTypeData,mii.cch,&rc,dwDrawFlags);
+ }
+
+ free(mii.dwTypeData);
+
+ RestoreDC(lpDIS->hDC,nIndexDC);
+ }
+ }
+ }
+ return TRUE;
+ case WM_INITMENUPOPUP:
+ {
+ HMENU hMenu;
+ int i, nCount;
+
+ hMenu = (HMENU) wParam;
+ nCount = GetMenuItemCount((HMENU) wParam);
+ for (i = 0; i < nCount; i++)
+ {
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID;
+ GetMenuItemInfo(hMenu, i, TRUE, &mii);
+
+ handle = getMenuHandle(pData->pMenuHandlesMap, (UINT) mii.wID);
+ if (handle) handleMenuUpdate(handle);
+ }
+ }
+ break;
}
Index: Menu.c
===================================================================
RCS file: /cvsroot/htoolkit/port/src/cbits/Win32/Menu.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** Menu.c 1 Apr 2003 23:54:20 -0000 1.5
--- Menu.c 23 Apr 2003 21:48:53 -0000 1.6
***************
*** 4,13 ****
#include "Handlers_stub.h"
- static UINT gMenuItemID = 0;
! static UINT NextMenuItemID()
! {
! return ++gMenuItemID;
! }
static void AddAccelString(int nKeyCode, int mods, char *text)
--- 4,21 ----
#include "Handlers_stub.h"
! #define CHECK_MENU_TYPE(handle,mask,ret) \
! if (((handle ? handle->type : MENU_POPUP) & (mask)) == 0) \
! { \
! printf("Invalid menu handle type."); \
! return ret; \
! }
!
! #define CHECK_MENU_TYPE_V(handle,mask) \
! if (((handle ? handle->type : MENU_POPUP) & (mask)) == 0) \
! { \
! printf("Invalid menu handle type."); \
! return; \
! }
static void AddAccelString(int nKeyCode, int mods, char *text)
***************
*** 82,90 ****
}
- static HMENU getHMENU(HMENU hMenu)
- {
- return (hMenu) ? hMenu : GetMenu(ghWndFrame);
- }
-
static void updateMenuBar(MenuHandle parent)
{
--- 90,93 ----
***************
*** 106,202 ****
}
! MenuHandle osAddMenu(MenuHandle parent, char *title)
{
! HMENU hMenu, hParent;
! FrameData *pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! hMenu = CreateMenu();
! hParent = getHMENU(parent);
! if (pFrameData->DocumentInterface == 1)
! InsertMenu(hParent,-1,MF_BYPOSITION | MF_POPUP,(UINT)hMenu,title);
! else
! InsertMenu(hParent,GetMenuItemCount(hParent)-1,MF_BYPOSITION | MF_POPUP,(UINT)hMenu,title);
! updateMenuBar(parent);
!
! return hMenu;
};
! MenuHandle osAddMenuItem(MenuHandle parent, int key, unsigned int mods, char *title)
{
! UINT nMenuItemID = NextMenuItemID();
! char *temp = rmalloc(strlen(title)+32);
! strcpy(temp, title);
! AddAccelString(key, mods, temp);
! InsertMenu(getHMENU(parent),-1,MF_BYPOSITION | MF_STRING,nMenuItemID,temp);
! free(temp);
! updateMenuBar(parent);
! return (MenuHandle) nMenuItemID;
};
! MenuHandle osAddMenuCheckItem(MenuHandle parent, int key, unsigned int mods, char *title)
{
! UINT nMenuItemID = NextMenuItemID();
! char *temp = rmalloc(strlen(title)+32);
! strcpy(temp, title);
! AddAccelString(key, mods, temp);
! InsertMenu(getHMENU(parent),-1,MF_BYPOSITION | MF_STRING,nMenuItemID,title);
! free(temp);
! updateMenuBar(parent);
! return (MenuHandle) nMenuItemID;
};
! void osAddMenuSeparatorItem(MenuHandle parent)
{
! InsertMenu(getHMENU(parent),-1,MF_BYPOSITION | MF_SEPARATOR,0,NULL);
! updateMenuBar(parent);
}
! void osSetMenuItemEnabled(MenuHandle parent, MenuHandle item, BOOL bState)
{
! EnableMenuItem(getHMENU(parent), (UINT) item, (bState ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
};
! BOOL osGetMenuItemEnabled(MenuHandle parent, MenuHandle item)
{
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
! GetMenuItemInfo(getHMENU(parent), (UINT) item, FALSE, &mii);
! return (mii.fState & MFS_ENABLED) != 0;
};
! void osSetMenuItemChecked(MenuHandle parent, MenuHandle item, BOOL bState)
{
! CheckMenuItem(getHMENU(parent), (UINT) item, (bState ? MF_CHECKED : MF_UNCHECKED) | MF_BYCOMMAND);
};
! BOOL osGetMenuItemChecked(MenuHandle parent, MenuHandle item)
{
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
! GetMenuItemInfo(getHMENU(parent), (UINT) item, FALSE, &mii);
return (mii.fState & MFS_CHECKED) != 0;
}
! void osSetMenuItemLabel(MenuHandle parent, MenuHandle item, int key, unsigned int mods, char* title)
{
! MENUITEMINFO menuItemInfo;
! char *temp = rmalloc(strlen(title)+32);
! strcpy(temp, title);
! AddAccelString(key, mods, temp);
! memset(&menuItemInfo,0,sizeof(menuItemInfo));
! menuItemInfo.cbSize = sizeof(menuItemInfo);
! menuItemInfo.fMask = MIIM_STRING;
! menuItemInfo.fType = MFT_STRING;
! menuItemInfo.dwTypeData = temp;
! menuItemInfo.cch = strlen(temp);
! SetMenuItemInfo(getHMENU(parent), (UINT) item, FALSE, &menuItemInfo);
! free(temp);
}
! void osDrawMenuBar(WindowHandle window)
{
! DrawMenuBar(window);
}
--- 109,508 ----
}
! MenuHandle osInsertMenu(MenuHandle parent, int pos)
{
! MenuHandle handle;
! FrameData *pFrameData;
! CHECK_MENU_TYPE(parent, MENU_POPUP, NULL);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! handle = newMenuHandle(pFrameData->pMenuHandlesMap, parent, MENU_POPUP, pos);
!
! if (handle)
! {
! handle->hMenu = CreateMenu();
!
! InsertMenu(getParentHMENU(handle),getMenuPos(pFrameData->pMenuHandlesMap, handle),MF_BYPOSITION | MF_POPUP,(UINT)handle->hMenu,"");
!
! updateMenuBar(parent);
! }
!
! return handle;
};
! MenuHandle osInsertMenuItem(MenuHandle parent, int pos)
{
! MenuHandle handle;
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE(parent, MENU_POPUP, NULL);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! handle = newMenuHandle(pFrameData->pMenuHandlesMap, parent, MENU_ITEM, pos);
!
! if (handle)
! {
! InsertMenu(getParentHMENU(handle),getMenuPos(pFrameData->pMenuHandlesMap, handle),MF_BYPOSITION | MF_STRING,handle->id,"");
! updateMenuBar(parent);
! }
!
! return handle;
};
! MenuHandle osInsertMenuCheckItem(MenuHandle parent, int pos)
{
! MenuHandle handle;
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE(parent, MENU_POPUP, NULL);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! handle = newMenuHandle(pFrameData->pMenuHandlesMap, parent, MENU_CHECK_ITEM, pos);
!
! if (handle)
! {
! InsertMenu(getParentHMENU(handle),getMenuPos(pFrameData->pMenuHandlesMap, handle),MF_BYPOSITION | MF_STRING,handle->id,"");
! updateMenuBar(parent);
! }
!
! return handle;
};
! MenuHandle osInsertMenuSeparatorItem(MenuHandle parent, int pos)
{
! MenuHandle handle;
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE(parent, MENU_POPUP, NULL);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! handle = newMenuHandle(pFrameData->pMenuHandlesMap, parent, MENU_SEPARATOR, pos);
!
! if (handle)
! {
! InsertMenu(getParentHMENU(handle),getMenuPos(pFrameData->pMenuHandlesMap, handle),MF_BYPOSITION | MF_SEPARATOR,0,NULL);
! updateMenuBar(parent);
! }
!
! return handle;
}
! MenuHandle osInsertMenuRadioGroup(MenuHandle parent, int pos)
{
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE(parent, MENU_POPUP, NULL);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
!
! return newMenuHandle(pFrameData->pMenuHandlesMap, parent, MENU_RADIO_GROUP, pos);
};
! MenuHandle osInsertMenuRadioItem(MenuHandle parent, int pos)
! {
! MenuHandle handle;
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE(parent, MENU_RADIO_GROUP, NULL);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! handle = newMenuHandle(pFrameData->pMenuHandlesMap, parent, MENU_RADIO_ITEM, pos);
!
! if (handle)
! {
! InsertMenu(getParentHMENU(handle),getMenuPos(pFrameData->pMenuHandlesMap, handle),MF_BYPOSITION | MF_STRING,handle->id,"");
! updateMenuBar(parent);
! }
!
! return handle;
! };
!
! void osDestroyMenu(MenuHandle handle)
! {
! int pos, count;
! HMENU hParent;
! FrameData *pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
!
! notifyHandleForDestroy(handle);
!
! hParent = getParentHMENU(handle);
! pos = getMenuPos(pFrameData->pMenuHandlesMap, handle);
!
! if (handle->type != MENU_RADIO_GROUP)
! DeleteMenu(hParent, pos, MF_BYPOSITION);
! else
! {
! count = getChildrenCount(pFrameData->pMenuHandlesMap, handle);
! while (count--)
! DeleteMenu(hParent, pos, MF_BYPOSITION);
! }
!
! deleteMenuHandle(pFrameData->pMenuHandlesMap, handle);
! }
!
! int osGetMenuItemCount(MenuHandle handle)
! {
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE(handle, MENU_RADIO_GROUP | MENU_POPUP, 0);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
!
! return getChildrenCount(pFrameData->pMenuHandlesMap, handle);
! }
!
! void osSetMenuItemEnabled(MenuHandle handle, BOOL bState)
! {
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE_V(handle, MENU_RADIO_ITEM | MENU_CHECK_ITEM | MENU_ITEM);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
!
! EnableMenuItem(getParentHMENU(handle), getMenuPos(pFrameData->pMenuHandlesMap, handle), (bState ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION);
! };
!
! BOOL osGetMenuItemEnabled(MenuHandle handle)
{
MENUITEMINFO mii;
+ FrameData *pFrameData;
+
+ CHECK_MENU_TYPE(handle, MENU_RADIO_ITEM | MENU_CHECK_ITEM | MENU_ITEM, FALSE);
+
+ pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
+
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
! GetMenuItemInfo(getParentHMENU(handle), getMenuPos(pFrameData->pMenuHandlesMap, handle), TRUE, &mii);
! return (mii.fState & MFS_DISABLED) == 0;
};
! void osSetMenuItemChecked(MenuHandle handle, BOOL bState)
{
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE_V(handle, MENU_CHECK_ITEM);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
!
! CheckMenuItem(getParentHMENU(handle), getMenuPos(pFrameData->pMenuHandlesMap, handle), (bState ? MF_CHECKED : MF_UNCHECKED) | MF_BYPOSITION);
!
! handleMenuCommand(handle);
};
! BOOL osGetMenuItemChecked(MenuHandle handle)
{
MENUITEMINFO mii;
+ FrameData *pFrameData;
+
+ CHECK_MENU_TYPE(handle, MENU_CHECK_ITEM, FALSE);
+
+ pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
+
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
! GetMenuItemInfo(getParentHMENU(handle), getMenuPos(pFrameData->pMenuHandlesMap, handle), TRUE, &mii);
return (mii.fState & MFS_CHECKED) != 0;
}
! void osSetMenuRadioGroupSelection(MenuHandle handle, int index)
{
! int pos;
! HMENU hParent;
! FrameData *pFrameData;
! MenuHandle child;
!
! CHECK_MENU_TYPE_V(handle, MENU_RADIO_GROUP);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! hParent = getParentHMENU(handle);
! pos = getMenuPos(pFrameData->pMenuHandlesMap, handle);
! child = getNthChild(pFrameData->pMenuHandlesMap, handle, index);
!
! if (!child) return;
!
! CheckMenuRadioItem(hParent, pos, pos+getChildrenCount(pFrameData->pMenuHandlesMap, handle)-1, pos+index, MF_BYPOSITION);
!
! handleMenuCommand(child);
! }
! int osGetMenuRadioGroupSelection(MenuHandle handle)
! {
! HMENU hParent;
! int pos, index;
! MenuHandle child;
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE(handle, MENU_RADIO_GROUP, -1);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! hParent = getParentHMENU(handle);
! pos = getMenuPos(pFrameData->pMenuHandlesMap, handle);
!
! index = 0;
! child = handle->children;
! while (child)
! {
! MENUITEMINFO mii;
! mii.cbSize = sizeof(mii);
! mii.fMask = MIIM_STATE;
! GetMenuItemInfo(hParent, pos+index, TRUE, &mii);
! if (mii.fState & MFT_RADIOCHECK)
! return index;
!
! index++;
! child = child->sibling;
! }
!
! return index;
}
! char *osGetMenuLabel(MenuHandle handle)
{
! int pos;
! HMENU hParent;
! char *s;
! MENUITEMINFO mii;
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE(handle, MENU_POPUP | MENU_RADIO_ITEM | MENU_CHECK_ITEM | MENU_ITEM, NULL);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! pos = getMenuPos(pFrameData->pMenuHandlesMap, handle);
! hParent = getParentHMENU(handle);
!
! memset(&mii,0,sizeof(mii));
! mii.cbSize = sizeof(mii);
! mii.fMask = MIIM_STRING;
! mii.fType = MFT_STRING;
! mii.dwTypeData = NULL;
! mii.cch = 0;
! GetMenuItemInfo(hParent, pos, TRUE, &mii);
! mii.cch++;
! mii.dwTypeData = malloc(mii.cch);
!
! if (mii.dwTypeData)
! {
! GetMenuItemInfo(hParent, pos, TRUE, &mii);
!
! s = mii.dwTypeData;
! while (*s && *s != '\t') s++;
! *s = 0;
! }
!
! return mii.dwTypeData;
! }
!
! void osSetMenuLabel(MenuHandle handle, char *title)
! {
! char *s, *temp;
! MENUITEMINFO mii;
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE_V(handle, MENU_POPUP | MENU_RADIO_ITEM | MENU_CHECK_ITEM | MENU_ITEM);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! temp = malloc(strlen(title)+32);
!
! if (temp)
! {
! s = temp;
! while (*title)
! {
! if (*title != '\t') *s++ = *title;
! title++;
! }
! *s = 0;
! AddAccelString(handle->key, handle->mods, temp);
!
! memset(&mii,0,sizeof(mii));
! mii.cbSize = sizeof(mii);
! mii.fMask = MIIM_STRING;
! mii.fType = MFT_STRING;
! mii.dwTypeData = temp;
! mii.cch = strlen(temp);
! SetMenuItemInfo(getParentHMENU(handle), getMenuPos(pFrameData->pMenuHandlesMap, handle), TRUE, &mii);
!
! updateMenuBar(handle->parent);
! }
!
! free(temp);
! }
!
! void osSetMenuItemAccel(MenuHandle handle, int key, unsigned int mods)
! {
! int pos;
! HMENU hParent;
! char *s;
! MENUITEMINFO mii;
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE_V(handle, MENU_RADIO_ITEM | MENU_CHECK_ITEM | MENU_ITEM);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! pos = getMenuPos(pFrameData->pMenuHandlesMap, handle);
! hParent = getParentHMENU(handle);
!
! updateAccelTable(pFrameData->pMenuHandlesMap, handle, key, mods);
!
! memset(&mii,0,sizeof(mii));
! mii.cbSize = sizeof(mii);
! mii.fMask = MIIM_STRING;
! mii.fType = MFT_STRING;
! mii.dwTypeData = NULL;
! mii.cch = 0;
! GetMenuItemInfo(hParent, pos, TRUE, &mii);
! mii.dwTypeData = malloc(mii.cch+32);
!
! if (mii.dwTypeData)
! {
! mii.cch++;
! GetMenuItemInfo(hParent, pos, TRUE, &mii);
!
! s = mii.dwTypeData;
! while (*s && *s != '\t') s++;
! *s = 0;
!
! AddAccelString(key, mods, s);
!
! mii.cch = strlen(mii.dwTypeData);
! SetMenuItemInfo(hParent, pos, TRUE, &mii);
!
! updateMenuBar(handle->parent);
! }
!
! free(mii.dwTypeData);
! }
!
! void osGetMenuItemAccel(MenuHandle handle, int *key, unsigned int *mods)
! {
! CHECK_MENU_TYPE_V(handle, MENU_RADIO_ITEM | MENU_CHECK_ITEM | MENU_ITEM);
!
! *key = handle->key;
! *mods = handle->mods;
! }
!
! void osSetMenuItemBitmap(MenuHandle handle, BitmapHandle bitmap)
! {
! MENUITEMINFO mii;
! FrameData *pFrameData;
!
! CHECK_MENU_TYPE_V(handle, MENU_ITEM);
!
! pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! handle->bitmap = bitmap;
!
! memset(&mii,0,sizeof(mii));
! mii.cbSize = sizeof(mii);
! mii.fMask = MIIM_FTYPE;
! mii.fType = bitmap ? MFT_OWNERDRAW : MFT_STRING;
! SetMenuItemInfo(getParentHMENU(handle), getMenuPos(pFrameData->pMenuHandlesMap, handle), TRUE, &mii);
!
! updateMenuBar(handle->parent);
! }
!
! int osGetMenuItemPos(MenuHandle handle)
! {
! FrameData *pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! return getMenuIndex(pFrameData->pMenuHandlesMap, handle);
}
Index: Util.c
===================================================================
RCS file: /cvsroot/htoolkit/port/src/cbits/Win32/Util.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** Util.c 30 Mar 2003 18:49:07 -0000 1.11
--- Util.c 23 Apr 2003 21:48:54 -0000 1.12
***************
*** 179,198 ****
}
! extern StgClosure GHCziConc_yield_closure;
void osStart()
{
MSG msg;
!
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
! TranslateMessage(&msg);
! DispatchMessage(&msg);
}
doneGdiPlus();
};
-
- extern void doneGdiPlus();
void osQuit()
--- 179,201 ----
}
! extern void doneGdiPlus();
void osStart()
{
MSG msg;
! FrameData *pFrameData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
!
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
! if ((pFrameData->DocumentInterface != 1 || !TranslateMDISysAccel(pFrameData->hClientWnd, &msg)) &&
! !TranslateAccelerator(pFrameData->hClientWnd, getAccelTableFromMap(pFrameData->pMenuHandlesMap), &msg))
! {
! TranslateMessage(&msg);
! DispatchMessage(&msg);
! }
}
doneGdiPlus();
};
void osQuit()
Index: Window.c
===================================================================
RCS file: /cvsroot/htoolkit/port/src/cbits/Win32/Window.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -C2 -d -r1.24 -r1.25
*** Window.c 2 Apr 2003 00:06:52 -0000 1.24
--- Window.c 23 Apr 2003 21:48:54 -0000 1.25
***************
*** 111,114 ****
--- 111,115 ----
case VK_F11: return kbF11;
case VK_F12: return kbF12;
+ case VK_CLEAR: return kbClear;
}
***************
*** 221,225 ****
else
{
! handleMenuCommand((MenuHandle) (UINT) LOWORD(wParam));
}
break;
--- 222,257 ----
else
{
! int pos, ppos;
! HMENU hParent;
! MENUITEMINFO mii;
! FrameData *pData = (FrameData *) GetWindowLong(ghWndFrame,GWL_USERDATA);
! MenuHandle handle = getMenuHandle(pData->pMenuHandlesMap, (UINT) LOWORD(wParam));
!
! if (handle)
! {
! hParent = getParentHMENU(handle);
! pos = getMenuPos(pData->pMenuHandlesMap, handle);
!
! mii.cbSize = sizeof(mii);
! mii.fMask = MIIM_STATE;
! GetMenuItemInfo(hParent, pos, TRUE, &mii);
!
! if ((mii.fState & MFS_DISABLED) == 0)
! {
! switch (handle->type)
! {
! case MENU_RADIO_ITEM:
! ppos = getMenuPos(pData->pMenuHandlesMap, handle->parent);
! CheckMenuRadioItem(hParent, ppos, ppos+getChildrenCount(pData->pMenuHandlesMap, handle->parent)-1, pos, MF_BYPOSITION);
! break;
! case MENU_CHECK_ITEM:
! CheckMenuItem(hParent, pos, ((mii.fState & MFS_CHECKED) ? MF_UNCHECKED : MF_CHECKED) | MF_BYPOSITION);
! break;
! default:
! }
!
! handleMenuCommand(handle);
! }
! }
}
break;
|