65.9K
CodeProject 正在变化。 阅读更多。
Home

菜单附加器

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.92/5 (6投票s)

2005年3月22日

2分钟阅读

viewsIcon

40279

downloadIcon

902

访问注册表,以便将自定义菜单追加到系统的菜单中。

Sample Image

引言

追加器将您自己的自定义菜单追加到右键单击文件夹或开始菜单时弹出的菜单中。当您需要随时使用的特定工具时,它非常有用。由于有些人经常使用命令提示符,在命令提示符和窗口之间切换非常不方便,这将在特定文件夹中打开命令提示符。一旦您需要通过追加器进行更改,就可以轻松地在该特定文件夹中打开命令提示符。无需经过漫长的过程,如“开始”->“运行”->“cmd”->“路径”(需要到达特定文件夹)。

背景

我从中获得灵感的追加器的原始版本是汇编语言编写的。它是随 MASM32 8.0 附带的一个工具。我将其转换为 C/SDK 应用程序。它不需要注册表 API 的知识。不过,我认为这篇文章对于那些想通过 C/SDK 学习注册表访问的人来说会很有帮助。我使用了自己编写的makefile(不是通过 VC++ 的导出makefile选项获得的标准makefile)。MSDN 提供了关于如何开始使用makefile的“NMAKE 参考”。请注意,学习makefile将使您倾向于学习 Cl.EXE(C 编译器)选项以及 LINK.EXE(链接器)选项。但这将是一个额外的优势,您将更深入地了解这些工具如何构建我们的可执行文件以将其加载到内存中。(Matt Pietrek,“Under the hood”,MSDN)。

使用代码

在与菜单:-对应的编辑框中键入您想要追加的菜单的名称。您可以在菜单名称前面使用 &,以便菜单名称将带下划线。例如,&Cmd 将显示为 Cmd。在命令编辑框中,键入应用程序的路径,在我们的例子中,在 Win 2000 上,C:\Winnt\System32\cmd.exe,在 Win 98 上,C:\Windows\Command.com。单击“应用”以将更改应用于注册表,或单击“删除”以删除已追加的菜单。请注意,单击“应用/删除”后,需要刷新Explorer.exe。我广泛使用了标准的注册表 API 来访问注册表,并使用 STRICT 模式编译。

/************************************
    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 宏也适用于 Unicode。

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

关注点

代码更加直观,您可以在 MSDN 上找到有关每个函数的信息。好的地方是用“0 错误 0 警告”编写高质量的代码。编写 STRICT 兼容代码是一门艺术。现在,此代码不支持错误处理。

© . All rights reserved.