Hello Luis,
I have noticed that I used the wrong jargon in my question. Using information by Bilal Durrani (Thanks !)
from an exchange on system menu, I use windows SDK function to expand the title bar menu ie systemmenu. I have added (most) source below.
If you are experienced with SDK (I am not) please comment on the use of the ID value range I use for the new items ie 1001, ..., 1004. Another question of mine is with respect to the use of a
zero-pointer when I forward the call in 'OpenglMenuInterim'. Also please, can you give advise on resetting the function pointers eg do I need to reset the pointer hProcOld when a panel is closed?
/*****************************************************/
/* windows SDK is needed */
/*****************************************************/
#include
/*****************************************************/
/* some defines */
/*****************************************************/
#define MENUOFFSET 1000
#define MENUITEMSMAX 4
#define MENUSEPARATOR 1
#define MENUSAVE 2
#define MENUPRINT 3
#define MENUCLIPBOARD 4
#define OPGLMAXPANELS 8
#define OPGLFRAMEWIDTH 640
#define OPGLFRAMEHEIGHT 480
#define OPGLFRAMESWITCH 2000
#define OPGLPAPERSIZEX 240.0
#define OPGLPAPERSIZEY 180.0
#define OPGLFRAMEOFFSET 23
#define OPGLFRAMEBORDER 0
char WindowTitle[10]="OPGL";
char WindowHint[60]="(mouse-lft=zoom in / mouse-rght = zoom out / ESC=reset)\0";
/*****************************************************/
/* structure for panel housekeeping data */
/* note that some data is redundant; I' am lazy */
/* - the number will be sequence number 0,1,.. */
/* - active will be set when window is created */
/* - panelid is the CVI panel id */
/* - hSsystem is corresponding windows handle */
/* Ignore the prefix 'opgl' as I do this for */
/* multiple panels with an OGL control */
/*****************************************************/
struct opglpanel_data {
int number;
int active;
int panelid;
... ...
... ...
long hProcOld;
long hSystem;
... ...
... ...
};
/*****************************************************/
/* global variable array for housekeeping data */
/*****************************************************/
struct opglpanel_data opglpanel[OPGLMAXPANELS];
/*****************************************************/
/* main function including init all global variables */
/* and creating first panel */
/*****************************************************/
int main (int argc, char *argv[])
{
int i, first=0;
for (i = 0; i < OPGLMAXPANELS; i++)
{
opglpanel[i].number = i;
opglpanel[i].active = 0;
opglpanel[i].panelid = -1;
... ...
... ...
opglpanel[i].hProcOld = 0;
opglpanel[i].hSystem = -1;
... ...
... ...
}
OpenglControlCreate(first);
}
/************************************/
/* find panelnumber for CVI panelid */
/************************************/
int OpenglControlPanel(int panelid)
{
int i, found = -1, error = -1;
if (panelid < 0) return(error);
for (i = 0; i < OPGLMAXPANELS; i++)
if (opglpanel[i].panelid == panelid) found = i;
return found;
}
/*********************************************/
/* find panelnumber for windows panel handle */
/*********************************************/
int OpenglControlWindow(long hwnd)
{
int i, found = -1, error = -1;
if (hwnd < 0) return(error);
for (i = 0; i < OPGLMAXPANELS; i++)
if (opglpanel[i].hSystem == hwnd) found = i;
return found;
}
/*****************************************************/
/* furtherdown, OpenglMenuInterim replaces initial windows callback */
/* check and process if one of the new menuitems has been selected */
/* subsequently send callback onwards to original callback */
/*****************************************************/
LRESULT APIENTRY OpenglMenuInterim(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
long orgproc;
long menuitem;
int panel;
panel = OpenglControlWindow((long)hwnd);
if ((uMsg == WM_SYSCOMMAND) && (wParam > MENUOFFSET) && (wParam <= (MENUOFFSET + MENUITEMSMAX)))
{
menuitem = wParam - MENUOFFSET;
switch(menuitem)
{
case MENUSAVE:
printf("Menu Save hwnd: %8d (panel %02d)", hwnd, panel );
break;
case MENUPRINT:
printf("Menu Print hwnd: %8d (panel %02d)", hwnd, panel );
break;
case MENUCLIPBOARD:
printf("Menu Clipboard hwnd: %8d (panel %02d)", hwnd, panel );
break;
default:
break;
}
}
if (panel >= 0) orgproc = opglpanel[panel].hProcOld;
else orgproc = 0; /* ????? ????? ????? */
return(CallWindowProc((WNDPROC)orgproc, hwnd, uMsg, wParam, lParam));
}
/*****************************************************/
/* discard panel ie with close button */
/* also reset all redirected callbacks to empty callback */
/*****************************************************/
void OpenglControlDiscard(int i)
{
int panelid, pictureid, controlid, discardid;
if ((i < 0) || (i >= OPGLMAXPANELS)) return;
panelid = opglpanel[i].panelid;
if (panelid > 0)
{
... ...
... ...
DiscardPanel(panelid);
}
opglpanel[i].panelid = -1;
opglpanel[i].hProcOld = 0;
opglpanel[i].hSystem = -1;
opglpanel[i].active = 0;
}
/*****************************************************/
/* create panel */
/*****************************************************/
int OpenglControlCreate(int i)
{
int panel;
int error = -1;
char title[80];
int hsystem, hitem;
long hproc;
HMENU hmenu;
if ((i < 0) || (i >= OPGLMAXPANELS)) return (error);
OpenglControlDiscard(i);
panel = NewPanel (0, "Open GL Frame", OPGLFRAMEOFFSET, OPGLFRAMEOFFSET,
OPGLFRAMEHEIGHT + 2 * OPGLFRAMEBORDER,
OPGLFRAMEWIDTH + 2 * OPGLFRAMEBORDER);
if (panel < 0)
{
sprintf(opglmessage, "Cannot create new panel for Open GL frame");
MessagePopup("Error: Create OPGL frame", opglmessage);
return (error);
}
SetPanelAttribute (panel, ATTR_SCALE_CONTENTS_ON_RESIZE, 1);
sprintf(title, "%s Panel #%1d %s", WindowTitle, i, WindowHint);
SetPanelAttribute (panel, ATTR_TITLE, title);
GetPanelAttribute (panel, ATTR_SYSTEM_WINDOW_HANDLE, &hsystem);
hmenu = GetSystemMenu((HWND)hsystem, FALSE);
hitem = MENUOFFSET + MENUSEPARATOR;
InsertMenu(hmenu, -1, MF_BYPOSITION | MF_SEPARATOR, hitem, "\0");
hitem = MENUOFFSET + MENUSAVE;
InsertMenu(hmenu, -1, MF_BYPOSITION | MF_STRING | MF_ENABLED, hitem, "Save\0");
hitem = MENUOFFSET + MENUPRINT;
InsertMenu(hmenu, -1, MF_BYPOSITION | MF_STRING | MF_ENABLED, hitem, "Print\0");
hitem = MENUOFFSET + MENUCLIPBOARD;
InsertMenu(hmenu, -1, MF_BYPOSITION | MF_STRING | MF_ENABLED, hitem, "Clipboard\0");
hproc = SetWindowLongPtr((HWND)hsystem, GWLP_WNDPROC, (long)OpenglMenuInterim);
DisplayPanel(panel);
opglpanel[i].panelid = panel;
... ...
... ...
opglpanel[i].hSystem = (long)hsystem;
opglpanel[i].hProcOld = hproc;
opglpanel[i].active = 1;
return (panel);
}