Click here to Skip to main content
15,883,709 members
Articles / Programming Languages / C
Article

Menu Appender

Rate me:
Please Sign up or sign in to vote.
2.92/5 (6 votes)
31 Mar 20052 min read 39.4K   900   10   7
Registry access, to append customized menu to system's menu.

Sample Image

Introduction

Appender appends your own customized menu to the popup menu that you get when you right click on a folder, or start menu. It's useful when you require a specific tool at your hand any time. Since some people use command prompt consistently, it's very uncomfortable to switch between windows to command prompt, that will open in specific folder. Once you do require changes by Appender, it's easy to open command prompt in that particular folder. No need to go through a lengthy process as START->RUN->cmd->PATH (required to reach a particular folder).

Background

Original version of Appender from which I got an idea, is in assembly. It is a tool which comes with MASM32 8.0. I converted it to a C/SDK application. It doesn't require knowledge of registry API. Though, I think this article will be good for those who want to learn registry access through C/SDK. I have used my own makefile (not standard one that you get through export makefile option from VC++). MSDN presents "NMAKE Reference" on how to start with makefile. Note that learning makefile will tend you to learn Cl.EXE (C compiler) options plus LINK.EXE (Linker) options. But it will be an added advantage, that you will get extra understanding of how these tools craft our executables to load it in memory. (Matt Pietrek, "Under the hood", MSDN).

Using the code

Type the name of the menu that you want to append, in the edit box against Menu:-. You can use & in front of the menu name so that the menu name will be underlined. Example, &Cmd causes it to appear as Cmd. In the command edit box, type the path to the application, in our case on Win 2000, C:\Winnt\System32\cmd.exe, and on Win 98, C:\Windows\Command.com. Click Apply to apply changes to registry, or click Remove to already appended menu. Note that after clicking Apply/Remove, Explorer.exe is to be refreshed. I have extensively used the standard registry API to access the registry, and compiled it with STRICT enabled.

/************************************
    Copyright (C) 2005, Pragmasoft.
    All rights reserved.

    Appender:- ARUN PAWAR 2005
    File    :- Appender.h
************************************/

#ifndef _Appender_
#define _Appender_

#pragma once

BOOL CALLBACK dlgProc(HWND,UINT,WPARAM,LPARAM);
__inline void _MB(HWND hDlg,LONG nResult);

#define DIM(a) ( sizeof(a)/sizeof(a[0]) )
#define MAXBUF 100

#endif //    _Appender_

DIM macro works with Unicode as well.

BOOL CALLBACK dlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    HINSTANCE hInst = NULL;
    HICON hIcon = NULL;
    HKEY hKey = NULL;
    HWND hEditMenu = NULL;
    LONG nResultMenu,nResultCommand,nResult = 0;

    TCHAR szAppName[MAXBUF],szCopyright[MAXBUF];
    TCHAR szMenu[MAXBUF],szCommand[MAXBUF];
    TCHAR szRegKeyMenu[MAXBUF],szRegKeyCommand[MAXBUF];

    hInst = (HINSTANCE) GetWindowLong(hDlg,GWL_HINSTANCE);

    LoadString(hInst,IDS_MENU,szRegKeyMenu,DIM(szRegKeyMenu));
    LoadString(hInst,IDS_COMMAND,szRegKeyCommand,DIM(szRegKeyCommand));

    switch( uMsg )
    {
    case WM_INITDIALOG:

        nResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, szRegKeyMenu, 
                                  0,KEY_QUERY_VALUE,&hKey);

        if( nResult == ERROR_SUCCESS )
        {
            int nMaxLen = 100;
            RegQueryValueEx(hKey,NULL,NULL,NULL,szMenu,&nMaxLen);
            RegCloseKey(hKey);
            SetDlgItemText(hDlg,IDMENU,szMenu);
        }

        nResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, szRegKeyCommand, 
                                     0,KEY_QUERY_VALUE,&hKey);

        if( nResult == ERROR_SUCCESS )
        {
            int nMaxLen = 100;
            RegQueryValueEx(hKey,NULL,NULL,NULL,szCommand,&nMaxLen);
            RegCloseKey(hKey);
            SetDlgItemText(hDlg,IDCOMMAND,szCommand);
        }

        hEditMenu = GetDlgItem(hDlg,IDMENU);
        SetFocus(hEditMenu);
        return FALSE;

    case WM_COMMAND:

        switch( wParam )
        {

        case IDAPPLY:

            GetDlgItemText(hDlg,IDMENU,szMenu,DIM(szMenu));
            GetDlgItemText(hDlg,IDCOMMAND,szCommand,DIM(szCommand));

            RegCreateKeyEx(HKEY_CLASSES_ROOT,szRegKeyMenu,0,NULL,
              REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,0);
            nResultMenu = RegSetValue(HKEY_CLASSES_ROOT,
              szRegKeyMenu,REG_SZ,szMenu,DIM(szMenu));
            RegCloseKey(hKey);

            RegCreateKeyEx(HKEY_CLASSES_ROOT,szRegKeyCommand,0,NULL,
              REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,0);
            nResultCommand = RegSetValue(HKEY_CLASSES_ROOT,
              szRegKeyCommand,REG_SZ,szCommand,DIM(szCommand));

            if( (nResultMenu && nResultCommand) == ERROR_SUCCESS )
                MessageBox(hDlg,_T("New menu option appended"),
                                      _T("Success!..."),MB_OK);

            RegCloseKey(hKey);
            return TRUE;

        case IDQUIT:

            EndDialog(hDlg,0);
            return TRUE;

        case IDREMOVE:

            nResult = RegOpenKeyEx(HKEY_CLASSES_ROOT,szRegKeyCommand, 
                                         0,KEY_ALL_ACCESS,&hKey);

            if( nResult == ERROR_SUCCESS )
            {
                nResultCommand = RegDeleteKey(HKEY_CLASSES_ROOT,szRegKeyCommand);
            }

            nResult = RegOpenKeyEx(HKEY_CLASSES_ROOT,szRegKeyMenu, 
                                      0,KEY_ALL_ACCESS,&hKey);

            if( nResult == ERROR_SUCCESS )
            {
                nResultMenu = RegDeleteKey(HKEY_CLASSES_ROOT,szRegKeyMenu);
            }

            if( (nResultMenu && nResultCommand) == ERROR_SUCCESS )
                MessageBox(hDlg,_T("New menu option removed"),
                                _T("Success!..."),MB_OK);

            RegCloseKey(hKey);

            SetDlgItemText(hDlg,IDMENU,NULL);
            SetDlgItemText(hDlg,IDCOMMAND,NULL);
            return TRUE;

        case ID_EXIT:

            EndDialog(hDlg,0);
            return TRUE;

        case ID_ABOUT:

            hIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON));

            LoadString(hInst,IDS_WNDNAME,szAppName,DIM(szAppName));
            LoadString(hInst,IDS_COPYRIGHT,szCopyright,DIM(szCopyright));

            ShellAbout(hDlg,szAppName,szCopyright,hIcon);
            return TRUE;

        }
    }
    return FALSE;
}

Points of Interest

Code is much more straightforward and you will get information about every function on MSDN. Good thing is writing quality code with "0 errors 0 warnings". Writing STRICT compliant code is an art. Right now, this code doesn't support error handling.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionAdding an icon to a context menu ? Pin
fdgf13-Feb-07 6:31
fdgf13-Feb-07 6:31 
AnswerRe: Adding an icon to a context menu ? Pin
@run 13-Feb-07 17:04
@run 13-Feb-07 17:04 
GeneralI have posted updated article so wait Pin
@run 25-Mar-05 0:18
@run 25-Mar-05 0:18 
GeneralRemoval is incomplete Pin
gxdata22-Mar-05 18:31
gxdata22-Mar-05 18:31 
GeneralRe: Removal is incomplete Pin
RealSkydiver22-Mar-05 21:44
RealSkydiver22-Mar-05 21:44 
GeneralRe: Removal is incomplete Pin
dzCepheus1-Apr-05 0:10
dzCepheus1-Apr-05 0:10 
GeneralRe: Removal is incomplete Pin
WREY23-Mar-05 5:21
WREY23-Mar-05 5:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.