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; |