Blame | Last modification | View Log | Download
/**************************************************************** Object : pvb_util.dll** File : menu.c** Purpose : Menu handling for FactoyyLink, usage of functions* with PVB.***************************************************************/#include <stdlib.h>#include <stdio.h>#include <windows.h>/** Defines*/#define PVB_MAX_MENU 25/** Global variables*/int menu_init = 0;int menu_busy = 0;int looping = 0;extern short act_cur_type;HMENU menu_bar[ PVB_MAX_MENU]; /* supported menu bar items */HMENU menu_itm[ PVB_MAX_MENU]; /* supported sub menu's for menu bar */HMENU menu_sub[ PVB_MAX_MENU]; /* supported sub menu's for menu bar */short menu_bar_type[ PVB_MAX_MENU]; /* supported menu bar items */short menu_itm_type[ PVB_MAX_MENU]; /* supported sub menu's for menu bar */short menu_sub_type[ PVB_MAX_MENU]; /* supported sub menu's for menu bar */HWND menu_hwnd[ PVB_MAX_MENU];HWND capt_hwnd[ PVB_MAX_MENU];WNDPROC lpPrevWndFunc[ PVB_MAX_MENU];POINT menu_point[ PVB_MAX_MENU];POINT dummy_point[ PVB_MAX_MENU];UINT last_event[ PVB_MAX_MENU];UINT last_type[ PVB_MAX_MENU];short mark[ PVB_MAX_MENU];short new_event[ PVB_MAX_MENU];HWND xhwnd;UINT xuMsg;WPARAM xwParam;LPARAM xlParam;extern HWND status_hwnd;/**************************************************************** Function: short WINAPI pvb_menu_init( void)** Purpose : Initialise handling of the menu's.* Prepare all the DLL's global parameters.** Return : 0 - Success* -1 - Failure**************************************************************/short WINAPI pvb_menu_init( void){int i;/* clear all menu items */memset( menu_bar, 0, PVB_MAX_MENU * sizeof( HMENU));memset( menu_itm, 0, PVB_MAX_MENU * sizeof( HMENU));memset( menu_sub, 0, PVB_MAX_MENU * sizeof( HMENU));memset( menu_bar_type, 0, PVB_MAX_MENU * sizeof( short));memset( menu_itm_type, 0, PVB_MAX_MENU * sizeof( short));memset( menu_sub_type, 0, PVB_MAX_MENU * sizeof( short));memset( menu_hwnd, 0, PVB_MAX_MENU * sizeof( HWND));memset( last_event, 0, PVB_MAX_MENU * sizeof( long));memset( mark, 0, PVB_MAX_MENU * sizeof( short));memset( new_event, 0, PVB_MAX_MENU * sizeof( short));memset( menu_point, 0, PVB_MAX_MENU * sizeof( POINT));memset( dummy_point, 0, PVB_MAX_MENU * sizeof( POINT));for (i = 0; i < PVB_MAX_MENU; i++){menu_bar[ i] = CreateMenu();menu_itm[ i] = CreateMenu();menu_sub[ i] = CreateMenu();}menu_busy = 0;menu_init = 1;return 0;} /* pvb_menu_init *//**************************************************************** Function : short WINAPI pvb_menubar_append( short index,* short item,* short type,* char *title,* short id)** Purpose : Append a menu itme to the mneu bar.** Parameter: index - Index (1 .. 100) for menu bar element.* item - Index of sub menu, zero for no sub menu.* type - Type of menu item:* bit 0: String, Separator.* bit 1: Not checked, Checked.* bit 2: Enabled, Disabled and grayed.* title - Text for the item* id - User id, returned if item is selected.** Return : 0 - Success* -1 - Failure**************************************************************/short WINAPI pvb_menubar_append( short index, short item,short type, char *title, short id){UINT ident = id;UINT flags = 0;short ret = 0;/* check initialisation */if (!menu_init)return -1;/* check the index */if ((index < 1) || (index > PVB_MAX_MENU))return -1;if ((item < 0) || (item > PVB_MAX_MENU))return -1;if ((id < 0) || (id > 999999))return -1;ident += 97000000;/* build the type */if (type & 0x1)flags |= MF_SEPARATOR;elseflags |= MF_STRING;if (type & 0x2)flags |= MF_CHECKED;if (type & 0x4)flags |= MF_GRAYED;/* save the menu item type */menu_bar_type[ index - 1] = type;if (!item){/* no sub menu for menu bar element */if (AppendMenu( menu_bar[ index - 1], flags, ident, title) != TRUE)ret = -1;}else{/* connect a sub menu */if (AppendMenu( menu_bar[ index - 1], MF_POPUP, (unsigned int)menu_itm[ item - 1], title) != TRUE)ret = -1;}return ret;} /* pvb_menu_bar_append *//**************************************************************** Function : short WINAPI pvb_menuitm_append( short index,* short sub,* short type,* char *title,* short id)** Purpose : Append a menu item to a menu item from the menubar.** Parameter: index - Index (1 .. 100) for menu item element.* sub - Index of sub menu, zero for no sub menu.* type - Type of menu item:* bit 0: String, Separator.* bit 1: Not checked, Checked.* bit 2: Enabled, Disabled and grayed.* title - Text for the item* id - User id, returned if item is selected.** Return : 0 - Success* -1 - Failure**************************************************************/short WINAPI pvb_menuitm_append( short index, short sub,short type, char *title, short id){UINT ident = id;UINT flags = 0;short ret = 0;/* check initialisation */if (!menu_init)return -1;/* check the index */if ((index < 1) || (index > PVB_MAX_MENU))return -1;if ((sub < 0) || (sub > PVB_MAX_MENU))return -1;if ((id < 0) || (id > 999999))return -1;ident += 97000000;/* build the type */if (type & 0x1)flags |= MF_SEPARATOR;elseflags |= MF_STRING;if (type & 0x2)flags |= MF_CHECKED;if (type & 0x4)flags |= MF_GRAYED;/* save the menu item type */menu_itm_type[ index - 1] = type;if (!sub){/* no sub menu for menu bar element */if (AppendMenu( menu_itm[ index - 1], flags, ident, title) != TRUE)ret = -1;}else{/* connect a sub menu */if (AppendMenu( menu_itm[ index - 1], MF_POPUP, (unsigned int)menu_sub[ sub - 1], title) != TRUE)ret = -1;}return ret;} /* pvb_menuitm_append *//**************************************************************** Function : short WINAPI pvb_menusub_append( short index,* short type,* char *title,* short id)** Purpose : Append a menu sub item to a menu item.** Parameter: index - Index (1 .. 100) for menu sub element.* type - Type of menu item:* bit 0: String, Separator.* bit 1: Not checked, Checked.* bit 2: Enabled, Disabled and grayed.* title - Text for the item* id - User id, returned if item is selected.** Return : 0 - Success* -1 - Failure**************************************************************/short WINAPI pvb_menusub_append( short index, short type,char *title, short id){UINT ident = id;UINT flags = 0;short ret = 0;/* check initialisation */if (!menu_init)return -1;/* check the index */if ((index < 1) || (index > PVB_MAX_MENU))return -1;if ((id < 0) || (id > 999999))return -1;ident += 97000000;/* build the type */if (type & 0x1)flags |= MF_SEPARATOR;elseflags |= MF_STRING;if (type & 0x2)flags |= MF_CHECKED;if (type & 0x4)flags |= MF_GRAYED;/* save the menu item type */menu_sub_type[ index - 1] = type;/* no sub menu for menu bar element */if (AppendMenu( menu_sub[ index - 1], flags, ident, title) != TRUE)ret = -1;return ret;} /* pvb_menusub_append */#ifdef kldjfdkljdkdlfjBOOL CALLBACK EnumChildProc(hwndChild, lParam)HWND hwndChild;LPARAM lParam;{LPRECT rcParent;int i, idChild;// Retrieve the child-window identifier. Use it to set the// position of the child window.idChild = GetWindowLong(hwndChild, GWL_ID);if (idChild == ID_FIRSTCHILD)i = 0;else if (idChild == ID_SECONDCHILD)i = 1;elsei = 2;// Size and position the child window.rcParent = (LPRECT) lParam;MoveWindow(hwndChild,(rcParent->right / 3) * i,0,rcParent->right / 3,rcParent->bottom,TRUE);// Make sure the child window is visible.ShowWindow(hwndChild, SW_SHOW);return TRUE;}#endif/**************************************************************** Function: LRESULT WINAPI PVB_MenuWndProc(HWND hwnd,* UINT uMsg,* WPARAM wParam,* LPARAM lParam)*** Purpose : Callback function for window message handling.** Return : Handling result of original call back function.**************************************************************/LRESULT WINAPI PVB_MenuWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam){RECT rect;RECT rcClient;RECT rcParent;short index;long x, y;float screen_x,screen_y,width,height,border_x,border_y,menu,caption,pvb_x,pvb_y;LONG style;/* now we need to find the index */for (index = 0; index < PVB_MAX_MENU; index++){if (hwnd == menu_hwnd[ index])break;}if (index < PVB_MAX_MENU){/* Filter for the needed messages */if (mark[ index]){SetCursorPos( menu_point[ index].x, menu_point[ index].y);SetCapture( capt_hwnd[ index]);mark[ index] = 0;}switch (uMsg){case WM_ENTERMENULOOP:case WM_EXITMENULOOP:case WM_ENTERIDLE:case WM_INITMENU:case WM_INITMENUPOPUP:case WM_MENUSELECT:case WM_SYSCHAR:case WM_MENUCHAR:case WM_SYSCOMMAND:break;case WM_SIZE: // main window changed size// Get the dimensions of the main window's client// area, and enumerate the child windows. Pass the// dimensions to the child windows during enumeration.// WM_SIZE// fwSizeType = wParam; // resizing flag// nWidth = LOWORD(lParam); // width of client area// nHeight = HIWORD(lParam); // height of client areaif (status_hwnd != NULL){// if (!looping)// {GetClientRect(status_hwnd, &rcClient);GetClientRect(hwnd, &rcParent);MoveWindow( status_hwnd, 0, rcParent.bottom - rcClient.bottom,rcParent.right, rcClient.bottom, TRUE);// MoveWindow( hwnd, 0, 0,// rcParent.right, rcParent.bottom - rcClient.bottom, TRUE);// Make sure the child window is visible.//ShowWindow(hwndChild, SW_SHOW);// lParam -= rcClient.bottom;// lParam /=2;// return DefWindowProc( hwnd, uMsg, wParam, lParam);// SetWindowPos( hwnd, HWND_TOP, 0, 0, rcParent.right, rcParent.bottom - rcClient.bottom, SWP_NOMOVE);// looping++;// }// else// looping = 0;}break;//return 0;default:break;}if (uMsg == WM_COMMAND){if ((wParam >= 97000000) && (wParam <= 98000000)){/* set the event code */mark[ index] = 1;last_event[ index] = wParam;last_type[ index] = GetMenuState( GetMenu(hwnd), /* handle of menu */last_event[ index], /* menu item to query */MF_BYCOMMAND); /* menu flags */new_event[ index] = 1;/* set the coordinates */GetCursorPos( &menu_point[ index]);/* retrieve the window styles */style = GetWindowLong( hwnd, GWL_STYLE);screen_x = (float)GetSystemMetrics( SM_CXSCREEN);screen_y = (float)GetSystemMetrics( SM_CYSCREEN);if ((style & WS_THICKFRAME) == WS_THICKFRAME){border_x = (float)(1 * GetSystemMetrics( SM_CXFRAME));border_y = (float)(1 * GetSystemMetrics( SM_CYFRAME));}else{border_x = (float)(1 * GetSystemMetrics( SM_CXFIXEDFRAME));border_y = (float)(1 * GetSystemMetrics( SM_CYFIXEDFRAME));}if ((style & WS_DLGFRAME) == WS_DLGFRAME)caption = (float)GetSystemMetrics( SM_CYCAPTION);menu = (float)GetSystemMetrics( SM_CYMENU);/* get window placement on screen */GetWindowRect( menu_hwnd[ index], /* handle of window */&rect); /* address of structure for window coordinates */width = (float)(rect.right - rect.left) - border_x;height = (float)(rect.bottom - rect.top) - border_y - menu - caption;if (width < (float)0)width = (float)0;if (height < (float)0)height = (float)0;/* now we need to correct for screen size, cause FL does it!!!! */if ((width / height) < (screen_x /screen_y)){/* adjust the height of the graphics */height = (screen_y * width) / screen_x;}else{/* adjust the width of the graphics */width = (screen_x * height) / screen_y;}/* get PVB coordinates */pvb_x = (float)32767;pvb_y = (float)((32767 * screen_y) / screen_x);/* correct bottom or right */x = (long)((width * dummy_point[ index].x) / pvb_x);x += rect.left;x += (long)border_x;y = (long)(height * (pvb_y - dummy_point[ index].y) / pvb_y);y += rect.top;y += (long)(menu + caption + border_y);capt_hwnd[ index] = GetCapture();SetCapture( hwnd);SetCursorPos( x, y);return 0;}}}/* execute the original callback function for handling messages */return CallWindowProc( lpPrevWndFunc[ index], /* pointer to previous procedure */hwnd, /* handle to window */uMsg, /* message */wParam, /* first message parameter */lParam); /* second message parameter */}/**************************************************************** Function : short WINAPI pvb_menu_create( short index,* char *title,* long x,* long y)** Purpose : Create menu for user.** Parameter: index - Index (1 .. 100) for menu bar element.* title - Window title name for which menu is to be* displayed.* x - Mouse position (x) for begin_pointed_at event.* y - Mouse position (y) for begin_pointed_at event.** Return : >= 1 - Success, return window handle.* -1 - Failure**************************************************************/short WINAPI pvb_menu_create( short index, char *title, long x, long y){HWND hwnd;short i;LONG style;if ((index < 1) || (index > PVB_MAX_MENU))return -1;if ((hwnd = FindWindow( NULL, title)) != NULL){/* check if window is already in use */for (i = 0; i < PVB_MAX_MENU; i++){if (menu_hwnd[ i] == NULL)break;}if (i >= PVB_MAX_MENU)return -2;if ((lpPrevWndFunc[ i] = (WNDPROC)SetWindowLong( hwnd, GWL_WNDPROC, (LONG)PVB_MenuWndProc)) != 0){style = GetWindowLong( hwnd, GWL_STYLE);style &= (~WS_POPUP);style &= (~WS_CLIPSIBLINGS);// style |= WS_CLIPCHILDREN;SetWindowLong( hwnd, GWL_STYLE, style);menu_hwnd[ i] = hwnd;SetMenu( hwnd, menu_bar[ index - 1]);DrawMenuBar( hwnd);dummy_point[ i].x = x;dummy_point[ i].y = y;}elsereturn -1;}return (i);} /* pvb_menu_create *//**************************************************************** Function : short WINAPI pvb_menu_object( short index,* long x,* long y)** Purpose : Adjust return object position.** Parameter: index - Index (1 .. 100) for menu bar element.* x - Mouse position (x) for begin_pointed_at event.* y - Mouse position (y) for begin_pointed_at event.** Return : 0 - Success, return window handle.* -1 - Failure**************************************************************/short WINAPI pvb_menu_object( short index, long x, long y){if (menu_hwnd[ index] == NULL)return -1;dummy_point[ index].x = x;dummy_point[ index].y = 24600L - y + GetSystemMetrics( SM_CYMENU);return 0;} /* pvb_menu_object *//**************************************************************** Function : short WINAPI pvb_menu_close( char *title)** Purpose : Remove menu from window.** Parameter: index - Window handle used in DLL.* Returned by the function 'pvb_menu_create'.** Return : 0 - Success* -1 - Failure**************************************************************/short WINAPI pvb_menu_close( short index){if ((index < 0) || (index >= PVB_MAX_MENU))return -1;/* see if the window exists */if (menu_hwnd[ index] == NULL)return -1;/* remove the hook */SetWindowLong( menu_hwnd[ index], GWL_WNDPROC, (LONG)lpPrevWndFunc[ index]);/* remove the menu bar */SetMenu( menu_hwnd[ index], NULL);DrawMenuBar( menu_hwnd[ index]);menu_hwnd[ index] = NULL;new_event[ index] = 0;mark[ index] = 0;return 0;} /* pvb_menu_close *//**************************************************************** Function : short WINAPI pvb_menu_event( short index,* short *checked)** Purpose : Check for last choosen menu item.** Parameter: index - Window handle used in DLL.* Returned by the function 'pvb_menu_create'.* flags - bit 0: checked (ON) or unchecked (OFF).* bit 1: grayed (ON) of enabled (OFF).* new - ON if this is a new choice, else OFF** Return : 0 - Success* 1 - New event* -1 - Failure**************************************************************/short WINAPI pvb_menu_event( short index, short *flags, short *new){short ret = 0;if (!menu_init)return -1;if ((index < 1) || (index > PVB_MAX_MENU))return -1;if (menu_hwnd[ index - 1] == NULL)return -1;if ((ret = (short)(last_event[ index - 1] - 97000000)) < 0)ret = 0;if ((last_type[ index - 1] & MF_CHECKED) == MF_CHECKED)*flags = 1;else*flags = 0;if ((last_type[ index - 1] & MF_GRAYED) == MF_GRAYED)*flags += 2;*new = new_event[ index - 1];new_event[ index - 1] = 0;return ret;} /* pvb_menu_event *//**************************************************************** Function : short WINAPI pvb_menu_checked( short type,* short index,* short item,* short checked)** Purpose : Change look of menu item to checked or non checked.** Parameter: type - Type of menu item, 0 = last selected one* 1 = menu bar* 2 = menu item* 3 = sub menu item* index - Menuar index, starting at one* item - Only used for types 1, 2, or 3, it is the* order number in the menu* check - New check status, 0 = non checked, 1 = checked.** Return : 0 - Success* -1 - Failure**************************************************************/short WINAPI pvb_menu_checked( short type, short index,short item, short checked){short ret = 0;UINT uCheck = 0;if (checked)uCheck = MF_CHECKED;elseuCheck = MF_UNCHECKED;switch (type){case 0:/* no type, use last selected item */if ((index < 0) || (index > PVB_MAX_MENU))return -1;uCheck |= MF_BYCOMMAND;CheckMenuItem( menu_bar[ index -1], /* handle to menu */last_event[ index - 1], /* menu item to check or uncheck */uCheck); /* menu item flags */break;case 1:uCheck |= MF_BYPOSITION;CheckMenuItem( menu_bar[ index - 1], /* handle to menu */item - 1, /* menu item to check or uncheck */uCheck); /* menu item flags */break;case 2:uCheck |= MF_BYPOSITION;CheckMenuItem( menu_itm[ index -1], /* handle to menu */item - 1, /* menu item to check or uncheck */uCheck); /* menu item flags */break;case 3:uCheck |= MF_BYPOSITION;CheckMenuItem( menu_sub[ index -1], /* handle to menu */item - 1, /* menu item to check or uncheck */uCheck); /* menu item flags */break;default:ret = -1;break;}return ret;} /* pvb_menu_checked *//**************************************************************** Function : short WINAPI pvb_menu_enabled( short type,* short index,* short item,* short checked)** Purpose : Change look of menu item to enabled or disabled.** Parameter: type - Type of menu item, 0 = last selected one* 1 = menu bar* 2 = menu item* 3 = sub menu item* index - Menuar index, starting at one* item - Only used for types 1, 2, or 3, it is the* order number in the menu* check - New enable status, 0 = enabled, 1 = disabled.** Return : 0 - Success* -1 - Failure**************************************************************/short WINAPI pvb_menu_enabled( short type, short index,short item, short checked){short ret = 0;UINT uCheck = 0;if (checked)uCheck = MF_GRAYED;elseuCheck = MF_ENABLED;switch (type){case 0:/* no type, use last selected item */if ((index < 0) || (index > PVB_MAX_MENU))return -1;uCheck |= MF_BYCOMMAND;EnableMenuItem( menu_bar[ index -1], /* handle to menu */last_event[ index - 1], /* menu item to check or uncheck */uCheck); /* menu item flags */break;case 1:uCheck |= MF_BYPOSITION;EnableMenuItem( menu_bar[ index - 1], /* handle to menu */item - 1, /* menu item to check or uncheck */uCheck); /* menu item flags */break;case 2:uCheck |= MF_BYPOSITION;EnableMenuItem( menu_itm[ index -1], /* handle to menu */item - 1, /* menu item to check or uncheck */uCheck); /* menu item flags */break;case 3:uCheck |= MF_BYPOSITION;EnableMenuItem( menu_sub[ index -1], /* handle to menu */item - 1, /* menu item to check or uncheck */uCheck); /* menu item flags */break;default:ret = -1;break;}return ret;} /* pvb_menu_enabled */