2010년 6월 26일 토요일

notepad2 컴파일 삽질기 부록#5.2 : context-menu 기능 수정

삽질기 부록#5.1 : context-menu 통합 및 수정을 수정한 포스팅. 부록 #5/#5.1과 본 포스트는 동시 적용불가.

구차니님께서 수고해주신 덕분에 context 메뉴(오른쪽 버튼 클릭 메뉴)를 통해 Notepad2를 사용할 수 있었다.
(삽질기 부록#1 : context-menu 추가삽질기 부록#2 : context-menu 추가 업그레이드 참조)

그런데, Notepad2 3.1.21 정식버전에서는 이 수정을 미묘하게 바꿔야 했으며, 이후 okto님구차니님과 context 메뉴에 대한 수정을 논의한 결과 메뉴를 조금 간결하게 변형하기로 했다.
(File 메뉴에 있는 context-menu 관련 메뉴를 하나만 남기도록 수정)

그리고, 레지스트리에 등록이 실패했을 때의 코드가 빠져있었는데, 실패했을 경우 간단한 경보음을 들려주도록 했다.

삽질기 1~3을 모두 적용했다고 가정하고 시작한다.
그리고, notepad2 컴파일 삽질기 부록#5.1 : context-menu 통합 및 수정은 적용하지 않은 상태에서 시작한다.


수정 대상파일은 resource.h, Notepad2.rc, Notepad2.c의 3개이며, 모두 src 폴더에 저장되어 있다.


1. resource.h

다음 한 줄을 추가.
#define IDM_REGISTRY_ALL            40690


2. Notepad2.rc

IDR_MAINWND MENU DISCARDABLE에서 아래 내용을 찾는다.
MENUITEM "Propert&ies...",              IDM_FILE_PROPERTIES
MENUITEM "Create &Desktop Link",        IDM_FILE_CREATELINK
MENUITEM SEPARATOR
POPUP "&Favorites"
BEGIN
    MENUITEM "&Open Favorites...\tAlt+I",   IDM_FILE_OPENFAV
    MENUITEM "&Add Current File...\tAlt+K", IDM_FILE_ADDTOFAV
    MENUITEM "&Manage...\tF9",              IDM_FILE_MANAGEFAV
END
이 부분을 아래와 같이 수정한다.
MENUITEM "Propert&ies...",              IDM_FILE_PROPERTIES
MENUITEM SEPARATOR
MENUITEM "Create &Desktop Link",        IDM_FILE_CREATELINK
MENUITEM "Add context-menu to all file type", IDM_REGISTRY_ALL, CHECKED
MENUITEM SEPARATOR
POPUP "&Favorites"
BEGIN
    MENUITEM "&Open Favorites...\tAlt+I",   IDM_FILE_OPENFAV
    MENUITEM "&Add Current File...\tAlt+K", IDM_FILE_ADDTOFAV
    MENUITEM "&Manage...\tF9",              IDM_FILE_MANAGEFAV
END

구분자 하나와 context-menu를 추가하는 내용임.


3. Notepad2.h

새로운 함수 하나를 추가.
void CheckRegistry();


4. Notepad2.c

파일 앞부분의 변수 선언부에 다음 내용을 추가.
BOOL      bRegistryUnknownType;
BOOL      bRegistryAllType;


다음, LRESULT CALLBACK MainWndProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam)에서 아래 내용을 찾는다.
case WM_COMMAND:
  return MsgCommand(hwnd,wParam,lParam);
여기에 아래와 같이 한 줄을 추가한다.
case WM_COMMAND:
  CheckRegistry();
  return MsgCommand(hwnd,wParam,lParam);


다음, void MsgInitMenu(HWND hwnd,WPARAM wParam,LPARAM lParam)에서 아래 내용을 찾는다.
EnableCmd(hmenu,IDM_EDIT_SELTONEXT,i);
EnableCmd(hmenu,IDM_EDIT_SELTOPREV,i && lstrlenA(efrData.szFind));
EnableCmd(hmenu,IDM_EDIT_REPLACE,i /*&& !bReadOnly*/);

CheckCmd(hmenu,IDM_VIEW_USE2NDDEFAULT,Style_GetUse2ndDefault(hwndEdit));
이 부분을 아래와 같이 수정한다. 1줄을 추가하는 것임.
EnableCmd(hmenu,IDM_EDIT_SELTONEXT,i);
EnableCmd(hmenu,IDM_EDIT_SELTOPREV,i && lstrlenA(efrData.szFind));
EnableCmd(hmenu,IDM_EDIT_REPLACE,i /*&& !bReadOnly*/);

CheckCmd(hmenu,IDM_REGISTRY_ALL,bRegistryAllType || bRegistryUnknownType);

CheckCmd(hmenu,IDM_VIEW_USE2NDDEFAULT,Style_GetUse2ndDefault(hwndEdit));


다음은 LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam)의 수정임.
이 함수는 전체가 하나의 switch-case 문으로 되어있는데, 이 case 중에 IDM_REGISTRY_ALL을 추가함.
case IDM_REGISTRY_ALL:
// Register registry - type all
if (bRegistryAllType || bRegistryUnknownType)
{
if (bRegistryAllType)
{
  //WinNT requires the key to have no subkeys
RegDeleteKey(HKEY_CLASSES_ROOT, L"*\\shell\\Open with notepad2\\command");
RegDeleteKey(HKEY_CLASSES_ROOT, L"*\\shell\\Open with notepad2");
bRegistryAllType = FALSE;
}
if (bRegistryUnknownType)
 {
//WinNT requires the key to have no subkeys
RegDeleteKey(HKEY_CLASSES_ROOT, L"Unknown\\shell\\Open with notepad2\\command");
RegDeleteKey(HKEY_CLASSES_ROOT, L"Unknown\\shell\\Open with notepad2");
bRegistryUnknownType = FALSE;
}
}
else
{
HKEY key1;
LONG res = RegCreateKey(HKEY_CLASSES_ROOT,L"*\\shell\\Open with notepad2",&key1);
bRegistryAllType = TRUE;
if (res == ERROR_SUCCESS)
{
WCHAR cmd[] = L"Open with &notepad2";
RegSetValue(key1, NULL, REG_SZ, cmd, wcslen(cmd));
}
else bRegistryAllType = FALSE;
RegCloseKey(key1);

  res = RegCreateKey(HKEY_CLASSES_ROOT,L"*\\shell\\Open with notepad2\\command",&key1);
if (res == ERROR_SUCCESS)
{
WCHAR cmd[MAX_PATH + 4];
WCHAR path[MAX_PATH];
int len;
GetModuleFileName(GetModuleHandle(NULL), path, MAX_PATH);
len = wsprintf(cmd, L"%s %%1", path);
RegSetValue(key1, NULL, REG_SZ, cmd, len);
}
else bRegistryAllType = FALSE;
RegCloseKey(key1);

if (!bRegistryAllType)
{
MessageBeep(MB_ICONEXCLAMATION);
}
}
break;


마지막으로 함수를 하나 추가한다.
void CheckRegistry()
{
    HKEY key;
    LONG res;

    res = RegOpenKey(HKEY_CLASSES_ROOT,L"*\\shell\\Open with notepad2",&key);
    if(res == ERROR_SUCCESS)
            bRegistryAllType = TRUE;
    else    bRegistryAllType = FALSE;
    RegCloseKey(key);

    res = RegOpenKey(HKEY_CLASSES_ROOT,L"unknown\\shell\\Open with notepad2",&key);
    if(res == ERROR_SUCCESS)
            bRegistryUnknownType = TRUE;
    else    bRegistryUnknownType = FALSE;
    RegCloseKey(key);
}

이렇게 수정하면 아래처럼 File 메뉴에서 context-menu 메뉴 하나가 표시된다.

사용자 삽입 이미지

context-menu가 하나만 나오도록 수정. ^^;


댓글 없음:

댓글 쓰기