Link to home
Start Free TrialLog in
Avatar of prashanthgn
prashanthgn

asked on

How to add entries to System pop up menu

How can I add entires to system pop up menu.
and how can I handle the events and messages
when an user clicks on it...?

-Prash
Avatar of Zoppo
Zoppo
Flag of Germany image

What exactly do you mean with 'system pop up menu'?

The system-menu of a window of your app which pops up when
clicking on the little icon in the top-left corner of the window (which contains i.e. 'Restore', 'Move', 'Size' ... 'Close')?

You can access this menu somehow like this:

1. Add a new resource symbol via 'View->Resource Symbols',
i.e. IDM_TEST.

This is from MSDN:
---------------------
In WM_SYSCOMMAND messages, the four low-order bits of the
wParam parameter are used internally by the system. To
obtain the correct result when testing the value of wParam,
 an application must combine the value 0xFFF0 with the
wParam value by using the bitwise AND operator.
---------------------

So, set the value of IDM_TEST to something like 0x...0, i.e. 0x1230.

Then add two message handlers to your window for
WM_SYSCOMMAND and WM_INITMENUPOPUP.

In your window's OnCreate() add code like:
 ...
 CMenu* pMenu = GetSystemMenu( FALSE );
 ASSERT( pMenu );

 if ( NULL == pMenu )
 return -1;

 // This tests if the menu item is in system-command range
 ASSERT((IDM_TEST & 0xFFF0) == IDM_TEST);
 ASSERT(IDM_TEST < 0xF000);

 pMenu->AppendMenu( MF_STRING, IDM_TEST, "Test" );
 return 0;
}

In the handler for WM_SYSCOMMAND add the functionality you
want to happen when the item is clicked, i.e.

void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ( nID == IDM_TEST )
  AfxMessageBox( "Test" );
 CMDIFrameWnd::OnSysCommand(nID, lParam);
}

In the handler for WM_INITMENUPOPUP you can control the state
of the item to en-/disable an (un-)check it, i.e.:
void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
 CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
     
 // We disable the item if no MDI child is present
 if ( NULL == MDIGetActive() )
  pPopupMenu->EnableMenuItem( IDM_TEST, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED );
 else
 pPopupMenu->EnableMenuItem( IDM_TEST, MF_BYCOMMAND | MF_ENABLED );
}


hope that helps,

ZOPPO
Adding Commands
===============

First we need to define a unique variable to represent each menu item. This can be done in the Resource.h file, or in any standard header file. If the commands already exist as part of another standard or conext menu, then this step can be skipped because the definitions already exist. However, it's important to note that even if we use the pre-existing definitions, the message handlers for the commands on the regular menu will NOT be automatically called. System commands are routed differently. So, in the end, it doesn't matter if we use the existing or define our own.

For our example, we'll define two:

#define IDM_ABOUT 16
#define IDM_EXIT  17
 



The IDM just means this is a menu-item ID.

We add these commands in our window's initializing function (OnInitDialog(), OnCreate()). My example is in a dialog class, so this is what the function looks like:


BOOL CBabelOnDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Add "About..." and "Exit" menu items to system menu.

    // Command IDs must be in system range
    // the ANDing is because of a bug in Windows 95

    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    ASSERT((IDM_EXIT & 0xFFF0) == IDM_EXIT);
    ASSERT(IDM_EXIT < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        pSysMenu->AppendMenu(MF_STRING,IDM_EXIT,"E&xit Program");
        pSysMenu->AppendMenu(MF_SEPARATOR);
        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, "A&bout BabelOn");
    }
.
.
.other initialization
 




Processing Custom Commands
==========================

In order to have those commands do anything, we can't rely on the normal message-handling mechanism, even if we have handlers for the same items in other menus. We have to handle the WM_SYSCOMMAND message in our dialog/window class.


void CBabelOnDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    //trap our own system menu messages
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    } else if ((nID & 0xFFF0)==SC_CLOSE){
        OnClose();
    } else if ((nID & 0xFFF0)==IDM_EXIT) {
        ::PostQuitMessage(0);
    }

     else {
   
        CDialog::OnSysCommand(nID, lParam);
    }
}
 

Good Luck
to Roshmon: did you test your code?

#define IDM_EXIT 17
ASSERT((IDM_EXIT & 0xFFF0) == IDM_EXIT);

will assert!
BTW, it's never a good idea to define resource IDs outside
of resource.h since then there's no way to grant resource
IDs are unique.

Hi Zoppo,
    I just got this document from the net. http://www.devhood.com It is a good site. I didn't tested the code.

Roshmon
Avatar of prashanthgn
prashanthgn

ASKER

Hi,

 I ahd asked for the menu which will be shown on right clicking on any of the files/directories in the Explorer
window, not for a specific application

-Prash
The below Registry is for right click on exe and then register…

So u can do the same for Jpeg through program using the APIs RegOpen, RegSet etc

 

 

REGEDIT4

 

; regsvr.reg, Copyright (c) 1997-1998, Chris Sells.

; All rights reserved. NO WARRANTIES ARE EXTENDED. USE AT YOUR OWN RISK.

; P.S. Enjoy and send comments to csells@sellsbrothers.com.

;

; History:

; 10/25/98

; Replaced %1 with %L to get long file name support.

; (Thanks to Sergey Tetkin for the suggestion!)

;

; Sometime in early 1997: 1st release

; Don, Tim, Keith and I were sitting around at a GCOM talking about

; what a pain it was to perform self-registeration and couldn't I

; add a shell extension to augment the context menu (I had written

; the Win95 course)? I said I could do even better than that and

; this regfile was born.

 

; Register and Unregister DLLs and OCXs

[HKEY_CLASSES_ROOT\.dll]

@="dllfile"

 

[HKEY_CLASSES_ROOT\.ocx]

@="dllfile"

 

[HKEY_CLASSES_ROOT\dllfile\shell\Register COM Server\command]

@="regsvr32 \"%L\""

 

[HKEY_CLASSES_ROOT\dllfile\shell\Unregister COM Server\command]

@="regsvr32 /u \"%L\""

 

; Register and Unregister EXEs

[HKEY_CLASSES_ROOT\.exe]

@="exefile"

 

[HKEY_CLASSES_ROOT\exefile\shell\Register COM Server\command]

@="\"%L\" /regserver"

 

[HKEY_CLASSES_ROOT\exefile\shell\Unregister COM Server\command]

@="\"%L\" /unregserver"



Good Luck
ASKER CERTIFIED SOLUTION
Avatar of Roshan Davis
Roshan Davis
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi,

 I ahd asked for the menu which will be shown on right clicking on any of the files/directories in the Explorer
window, not for a specific application

-Prash
Try This Link "The Complete Idiot's Guide to Writing Shell Extensions - Part II"
http://codeproject.com/shell/shellextguide2.asp?target=unregister%7Ccom%7Cserver

Good Luck
Hi,

 I ahd asked for the menu which will be shown on right clicking on any of the files/directories in the Explorer
window, not for a specific application

-Prash