notepad2 컴파일 삽질기 부록#6.1 : 메모장 대신 사용(수정)



okto님 배포본 notepad2는 설치 및 윈도우 메모장 대체를 위해 notepad.inf 파일을 이용했다.
이 방식은 설치가 쉽다는 장점은 있지만, 설치 제거에 손이 많이 간다는 단점이 있다.

장점을 살리고 단점을 제거하기 위해 구차니님께서 메모장을 대체하는 기능을 구현해주셨다.

그런데, 이를 위해 제작/공개한 notepad2 컴파일 삽질기 부록#6 : 메모장 대신 사용에는 사소한 버그가 하나 있었다.
바로 파일명을 notepad.exe로 바꾼 상태에선 동작하지 않는 다는 것이다.

이 부분은 사실 당연한 것이다.
이 기능은 레지스트리의 Image File Execution Options 키를 이용해서 notepad.exe라는 프로그램을 실행하면 다른 프로그램(notepad2.exe)을 실행하도록 지정하는 것인데, 그 프로그램이 또 notepad.exe라서 발생하는 문제이다.

이 기능을 사용하려면 소스 코드를 아래와 같이 수정하면 된다.

반드시 삽질기 부록#5.1 : context-menu 통합 및 수정을 적용한 후에 이 수정을 해야 함

수정 대상 파일은 역시 resource.h, Notepad2.rc, Notepad2.c 세 개이다.


1. resource.h

다음 줄을 추가한다.
#define IDM_REPLACE_NOTEPAD             40692



2. Notepad2.rc

아래 내용을 찾는다.
MENUITEM "Add context-menu to all file type", IDM_REGISTRY_ALL
, CHECKED
바로 앞에 다음 줄을 추가한다.
MENUITEM "Replace Notepad",             IDM_REPLACE_NOTEPAD



3. Notepad2.c

앞부분에 다음 변수를 하나 선언한다.
BOOL      bReplaceNotepad;


다음, void MsgInitMenu(HWND hwnd,WPARAM wParam,LPARAM lParam)에서 아래 내용을 찾는다.
CheckCmd(hmenu,IDM_REGISTRY_UNKNOWN,bRegistryUnknownType);
또는
CheckCmd(hmenu,IDM_REGISTRY_ALL,bRegistryAllType || bRegistryUnknownType);
바로 앞에 다음 줄을 추가한다.
CheckCmd(hmenu,IDM_REPLACE_NOTEPAD,bReplaceNotepad);


다음, LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam) 함수에 다음 case 문을 추가한다.
이 함수 전체가 하나의 switch-case 문으로 되어있는데, case를 하나 추가하는 것이다.
case IDM_REPLACE_NOTEPAD:
if (bReplaceNotepad)
{
//WinNT requires the key to have no subkeys
RegDeleteKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe");
bReplaceNotepad = FALSE;
}
else
{
WCHAR path[MAX_PATH], *wTemp;
GetModuleFileName(GetModuleHandle(NULL), path, MAX_PATH);
bReplaceNotepad = TRUE;

wTemp = path;
while (*wTemp) wTemp++;
if (_wcsicmp(wTemp-12, L"\\notepad.exe"))
{
HKEY key1;
LONG res = RegCreateKey(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe",&key1);
if (res == ERROR_SUCCESS)
{
WCHAR cmd[MAX_PATH + 4];
int len = wsprintf(cmd, L"\"%s\" /z", path);
RegSetValueExW(key1, L"Debugger", 0, REG_SZ, (const unsigned char*)cmd, len * 2);
}
else
{
bReplaceNotepad = FALSE;
MessageBeep(MB_ICONEXCLAMATION);
}
RegCloseKey(key1);
}
else
{
bReplaceNotepad = FALSE;
MessageBeep(MB_ICONEXCLAMATION);
}
}
break;


마지막으로 void CheckRegistry() 함수의 마지막 부분에 다음 내용을 추가하면 된다.
res = RegOpenKey(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe",&key);
if(res == ERROR_SUCCESS)
        bReplaceNotepad = TRUE;
else    bReplaceNotepad = FALSE;
RegCloseKey(key);


수정에 수고해주신 구차니님께 다시 한 번 감사드립니다.