ÆÄÀÏ »ðÀÔ ±â´ÉÀº ÆíÁýÇÏ´Â ÆÄÀÏ Áß°£¿¡ ¿ÜºÎÀÇ ´Ù¸¥ ÆÄÀÏ ³»¿ëÀ» »ðÀÔÇÏ´Â ±â´ÉÀÌ´Ù. Ŭ¸³º¸µå¸¦ »ç¿ëÇϸé Á÷Á¢ ÆÄÀÏÀ» »ðÀÔÇÒ ¼öµµ ÀÖÀ¸¹Ç·Î »ç½Ç ²À ÇÊ¿äÇÑ Çʼö ±â´ÉÀº ¾Æ´Ï´Ù. ±¸»öÀ» ¸ÂÃß±â À§ÇÑ ±â´ÉÀÏ »ÓÀÌ´Ù. Dangeun.cpp¿¡ ´ÙÀ½ ÇÔ¼ö¸¦ Ãß°¡ÇÑ´Ù.
void InsertFile(CApiEditText *pView)
{
OPENFILENAME OFN;
TCHAR lpstrFile[MAX_PATH]={0,};
HANDLE hFile;
DWORD dwRead,dwSize;
TCHAR *TextBuf;
memset(&OFN, 0, sizeof(OPENFILENAME));
OFN.lStructSize = sizeof(OPENFILENAME);
OFN.hwndOwner=g_hFrameWnd;
OFN.lpstrFilter="¸ðµç ÆÄÀÏ(*.*)\0*.*\0ÅؽºÆ® ÆÄÀÏ\0*.txt\0";
OFN.lpstrFile=lpstrFile;
OFN.nMaxFile=MAX_PATH;
OFN.Flags=OFN_EXPLORER;
if (GetOpenFileName(&OFN)) {
hFile=CreateFile(lpstrFile,GENERIC_READ,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile==INVALID_HANDLE_VALUE) {
MessageBox(g_hFrameWnd, "ÆÄÀÏÀ» ¿ ¼ö ¾ø½À´Ï´Ù","¾Ë¸²",MB_OK);
return;
}
dwSize=GetFileSize(hFile,NULL);
if (dwSize > 30*1048576) {
MessageBox(g_hFrameWnd, "ÃÖ´ë 30M±îÁö¸¸ »ðÀÔÇÒ ¼ö ÀÖ½À´Ï´Ù.","¾Ë¸²",MB_OK);
} else {
TextBuf=(TCHAR *)malloc(dwSize+2);
ReadFile(hFile,TextBuf,dwSize,&dwRead,NULL);
TextBuf[dwRead]=0;
TextBuf[dwRead+1]=0;
pView->InsertText(TextBuf);
free(TextBuf);
}
CloseHandle(hFile);
}
}
ÆÄÀÏ ¿±â °øÅë ´ëÈ»óÀÚ·Î ÅؽºÆ® ÆÄÀÏÀÇ °æ·Î¸¦ ÀԷ¹ްí ÀÌ ÆÄÀÏÀ» ¹öÆÛ·Î ÀÐÀº ÈÄ InsertText ÇÔ¼ö·Î È°¼ºÃ¢¿¡ »ðÀÔÇÑ´Ù. ¸Þ´º ¼±Åýà OnCommand¿¡¼ ÀÌ ÇÔ¼ö¸¦ È£ÃâÇϱ⸸ ÇÏ¸é µÈ´Ù.
void OnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
....
case IDM_EDIT_INSERTFILE:
InsertFile(pView);
break;
¸¸¾à È°¼ºÃ¢ÀÌ Àбâ Àü¿ëÀ̶ó¸é InsertText ÇÔ¼ö ¼±µÎ¿¡¼ ¿¡·¯ Á¡°ËÀ» ÇÏ¿© »ðÀÔÀÌ °ÅºÎµÈ´Ù. °£´ÜÇÑ ±â´ÉÀ̶ó ÀÛ¼ºÇÒ Äڵ嵵 ªÁö¸¸ »ç½Ç ÀÌ ±â´É¿¡´Â ¾ÆÁ÷ ¹®Á¦°¡ Á» ÀÖ´Ù. InsertText ÇÔ¼ö°¡ ÀÌÁø ÆÄÀÏÀ» ÀνÄÇÏÁö ¾ÊÀ¸¹Ç·Î ÅؽºÆ® ÆÄÀϸ¸ »ðÀÔÇÒ ¼ö ÀÖ´Ù. ÀÌÁø ÆÄÀÏÀ» ÅؽºÆ® Áß°£¿¡ »ðÀÔÇÏ´Â °æ¿ì°¡ ¾øÀ» °Í °°¾Æ º°´Ù¸¥ 󸮸¦ ÇÏÁö ¾Ê¾Ò´Ù. ÇÏÁö¸¸ À¯´ÏÄÚµå ¹®¼¸¦ »ðÀÔÇÏ´Â °æ¿ì´Â È°¼ºÃ¢ÀÇ Æ÷¸Ë¿¡ ¸Â°Ô º¯È¯ÇØ¾ß ÇÏ´Â ¹®Á¦°¡ ÀÖ´Ù.
Ư¼ö¹®ÀÚ´Â Å°º¸µå·Î Á÷Á¢ ÀÔ·ÂÇÒ ¼ö ¾ø´Â ±×·¡ÇÈ ¹®ÀÚÀÌ´Ù. À©µµ¿ìÁî¿¡ Æ÷ÇÔµÈ ¹®ÀÚÇ¥ ¾ÖÇø´À» »ç¿ëÇÒ ¼öµµ ÀÖÁö¸¸ ÆíÁý±â ³»¿¡¼ ÀÚÁÖ ¾²´Â Ư¼ö¹®ÀÚ Á¤µµ´Â Áö¿øÇÏ´Â °ÍÀÌ ÁÁ´Ù. Ư¼ö¹®ÀÚ ¸ñ·ÏÀ» ´ëÈ»óÀÚ¿¡ º¸¿© ÁÖ°í ¼±ÅÃÇϵµ·Ï ÇÑ´Ù. Ç¥ÁØ ÄÁÆ®·ÑÁß¿¡ ¸ñ·Ï Ãâ·Â¿¡ »ç¿ëÇÒ¸¸ÇÑ ±×¸®µå ÄÁÆ®·ÑÀÌ ¾øÀ¸¹Ç·Î º°µµÀÇ ÄÁÆ®·ÑÀÌ ÇÊ¿äÇÏ´Ù. WinMain¿¡ ´ÙÀ½ À©µµ¿ì Ŭ·¡½º¸¦ ¼±¾ðÇÑ´Ù.
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
,LPSTR lpszCmdParam,int nCmdShow)
{
....
WndClassEx.lpszClassName="DGStringGrid";
WndClassEx.lpfnWndProc=(WNDPROC)DGStringGridProc;
WndClassEx.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
WndClassEx.style=CS_DBLCLKS;
RegisterClassEx(&WndClassEx);
À©µµ¿ì ¹ÙÅÁ»ö°ú °°Àº ¹è°æ»öÀ» °¡Áö¸ç ´õºí Ŭ¸¯ ÀÔ·ÂÀ» ¹Þ¾Æ¾ß ÇÑ´Ù. ´ëÈ»óÀÚ´Â ´ÙÀ½°ú °°ÀÌ µðÀÚÀεǾî ÀÖ´Ù.
Áß¾ÓÀÇ ¹öÆ° ÀÚ¸®¿¡ ¹®ÀÚÇ¥ ÄÁÆ®·ÑÀÌ ¹èÄ¡µÉ °ÍÀÌ´Ù. Ä¿½ºÅÒ ÄÁÆ®·Ñµµ ´ëÈ»óÀÚ¿¡ ³õÀ» ¼ö ÀÖÁö¸¸ ÀýÂ÷°¡ ±î´Ù·Ó±â ¶§¹®¿¡ Ç¥ÁØ ÄÁÆ®·ÑÀ» ÀÏ´Ü ¹èÄ¡ÇÏ°í ½ÇÇàÁß¿¡ ´ëüÇÏ´Â ¹æ¹ýÀ» »ç¿ëÇÑ´Ù. ´ëÈ»óÀÚ ÇÁ·Î½ÃÀú¿Í ¹®ÀÚÇ¥ À©µµ¿ìÀÇ ÇÁ·Î½ÃÀú¸¦ ÀÛ¼ºÇÑ´Ù.
static int g_cat, g_nx, g_ny;
enum {GRID_PGUP, GRID_PGDN, GRID_DBLCLK, GRID_CHG};
BOOL CALLBACK SpecialDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
static CApiEditText *pView;
static TCHAR *szCategory[]={"µµÇü1","µµÇü2","Àü°¢ ¹®ÀÚ","ÇÑ±Û ³¹±ÛÀÚ","±×¸®½º ¹®ÀÚ",
"¼±¹®ÀÚ","µµ·®Çü","¿ø¹®ÀÚ","°ýÈ£¹®ÀÚ","È÷¶ó°¡³ª","°¡Å¸Ä«³ª","·¯½Ã¾Æ¾î"};
static HWND hGrid;
RECT brt;
int i,code;
TCHAR szTemp[16];
switch(iMessage) {
case WM_INITDIALOG:
MoveToParentCenter(hDlg);
pView=(CApiEditText *)lParam;
for (i=0;i<ARSIZE(szCategory);i++) {
SendDlgItemMessage(hDlg,IDC_LISTCATEGORY,LB_ADDSTRING,0,(LPARAM)szCategory[i]);
}
SendDlgItemMessage(hDlg,IDC_LISTCATEGORY,LB_SETCURSEL,g_cat,0);
GetWindowRect(GetDlgItem(hDlg,IDC_BTNCHARMAP),&brt);
ScreenToClient(hDlg,(LPPOINT)&brt);
hGrid=CreateWindowEx(WS_EX_CLIENTEDGE,"DGStringGrid",NULL,
WS_CHILD | WS_VISIBLE | WS_TABSTOP,
brt.left,brt.top,26*16+2,26*6+2,hDlg,(HMENU)0,g_hInst,NULL);
MoveWindow(GetDlgItem(hDlg,IDCANCEL),brt.left+26*16+2-90,brt.top+26*6+2+15,90,22,TRUE);
MoveWindow(GetDlgItem(hDlg,IDOK),brt.left+26*16+2-190,brt.top+26*6+2+15,90,22,TRUE);
MoveWindow(GetDlgItem(hDlg,IDC_STCODE),brt.left,brt.top+26*6+2+15,40,22,TRUE);
MoveWindow(GetDlgItem(hDlg,IDC_EDCODE),brt.left+45,brt.top+26*6+2+15,90,22,TRUE);
SetWindowPos(hDlg,HWND_NOTOPMOST,0,0,brt.left+26*16+2+12,
brt.top+26*6+2+15+22+25+GetSystemMetrics(SM_CYCAPTION),SWP_NOMOVE);
SetFocus(hGrid);
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case 0:
switch (HIWORD(wParam)) {
case GRID_PGUP:
if (g_cat > 0) {
g_cat--;
SendDlgItemMessage(hDlg,IDC_LISTCATEGORY,LB_SETCURSEL,g_cat,0);
InvalidateRect(hGrid,NULL,TRUE);
}
break;
case GRID_PGDN:
if (g_cat < ARSIZE(szCategory)-1) {
g_cat++;
SendDlgItemMessage(hDlg,IDC_LISTCATEGORY,LB_SETCURSEL,g_cat,0);
InvalidateRect(hGrid,NULL,TRUE);
}
break;
case GRID_DBLCLK:
SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDOK,0),0);
break;
case GRID_CHG:
code=0xa1a1+g_cat*0x100+g_ny*16+g_nx;
wsprintf(szTemp,"%d(%X)",code,code);
SetDlgItemText(hDlg,IDC_EDCODE,szTemp);
break;
}
break;
case IDC_LISTCATEGORY:
switch (HIWORD(wParam)) {
case LBN_SELCHANGE:
g_cat=SendDlgItemMessage(hDlg,IDC_LISTCATEGORY,LB_GETCURSEL,0,0);
InvalidateRect(hGrid,NULL,TRUE);
break;
}
break;
case IDOK:
code=0xa1a1+g_cat*0x100+g_ny*16+g_nx;
szTemp[0]=code >> 8;
szTemp[1]=code & 0xff;
szTemp[2]=0;
pView->InsertText(szTemp);
return TRUE;
case IDCANCEL:
EndDialog(hDlg,IDCANCEL);
return TRUE;
}
return FALSE;
}
return FALSE;
}
LRESULT CALLBACK DGStringGridProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
POINT pt;
int i,j;
RECT crt,nrt;
TCHAR Text[3]={0,};
HPEN hPen,OldPen;
switch(iMessage) {
case WM_GETDLGCODE:
return DLGC_WANTARROWS;
case WM_SETFOCUS:
case WM_KILLFOCUS:
InvalidateRect(hWnd,NULL,TRUE);
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd, &ps);
GetClientRect(hWnd,&crt);
hPen=CreatePen(PS_SOLID,1,RGB(128,128,128));
OldPen=(HPEN)SelectObject(hdc,hPen);
for (i=1;i<16;i++) {
MoveToEx(hdc,i*26,0,NULL);
LineTo(hdc,i*26,crt.bottom);
}
for (i=1;i<6;i++) {
MoveToEx(hdc,0,i*26,NULL);
LineTo(hdc,crt.right,i*26);
}
SetRect(&nrt,g_nx*26,g_ny*26,g_nx*26+26,g_ny*26+26);
FillRect(hdc,&nrt,GetSysColorBrush(COLOR_HIGHLIGHT));
if (GetFocus() == hWnd) {
DrawFocusRect(hdc,&nrt);
}
SetBkMode(hdc,TRANSPARENT);
SetTextAlign(hdc,TA_CENTER);
GetTextMetrics(hdc,&tm);
for (i=0;i<16;i++) {
for (j=0;j<6;j++) {
Text[0]=0xa1+g_cat;
Text[1]=0xa1+j*16+i;
if (i==g_nx && j==g_ny) {
SetTextColor(hdc,RGB(255,255,255));
} else {
SetTextColor(hdc,RGB(0,0,0));
}
TextOut(hdc,i*26+13,j*26+(26-tm.tmHeight)/2,Text,2);
}
}
DeleteObject(SelectObject(hdc,OldPen));
EndPaint(hWnd, &ps);
return 0;
case WM_LBUTTONDOWN:
SetFocus(hWnd);
pt.x=LOWORD(lParam)/26;
pt.y=HIWORD(lParam)/26;
if (pt.x!=g_nx || pt.y!=g_ny) {
g_nx=pt.x;
g_ny=pt.y;
InvalidateRect(hWnd,NULL,TRUE);
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,GRID_CHG),(LPARAM)hWnd);
}
return 0;
case WM_LBUTTONDBLCLK:
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,2),(LPARAM)hWnd);
return 0;
case WM_KEYDOWN:
switch (wParam) {
case VK_LEFT:
if (g_nx > 0) {
g_nx--;
} else if (g_ny > 0) {
g_nx=15;
g_ny--;
}
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,GRID_CHG),(LPARAM)hWnd);
InvalidateRect(hWnd,NULL,TRUE);
break;
case VK_RIGHT:
if (g_nx < 15) {
g_nx++;
} else if (g_ny < 5) {
g_nx=0;
g_ny++;
}
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,GRID_CHG),(LPARAM)hWnd);
InvalidateRect(hWnd,NULL,TRUE);
break;
case VK_UP:
if (g_ny > 0) {
g_ny--;
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,GRID_CHG),(LPARAM)hWnd);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case VK_DOWN:
if (g_ny < 5) {
g_ny++;
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,GRID_CHG),(LPARAM)hWnd);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case VK_PRIOR:
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,GRID_PGUP),(LPARAM)hWnd);
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,GRID_CHG),(LPARAM)hWnd);
break;
case VK_NEXT:
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,GRID_PGDN),(LPARAM)hWnd);
SendMessage(GetParent(hWnd),WM_COMMAND,MAKEWPARAM(0,GRID_CHG),(LPARAM)hWnd);
break;
}
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
¼¼ °³ÀÇ Àü¿ª º¯¼ö°¡ ¼±¾ðµÇ¾î Àִµ¥ g_cat´Â Ä«Å×°í¸®, Áï ¾î¶² ¹®ÀÚÁýÇÕÀ» º¸¿© ÁÖ°í ÀÖ´ÂÁö¸¦ ±â¾ïÇϸç g_nx, g_ny´Â ¹®ÀÚÇ¥¿¡¼ ÇöÀç °¡¸®Å°°í ÀÖ´Â ¹®ÀÚÀÇ ÁÂÇ¥°ªÀÌ´Ù. ¹®ÀÚÇ¥ ÄÁÆ®·ÑÀº Àڽſ¡°Ô º¯È°¡ ÀÖÀ» ¶§ ºÎ¸ð À©µµ¿ì¿¡°Ô ÅëÁö ¸Þ½ÃÁö¸¦ º¸³»´Âµ¥ 4°¡Áö ÅëÁö ¸Þ½ÃÁö°¡ ¼±¾ðµÇ¾î ÀÖ´Ù.
´ëÈ»óÀÚ ÇÁ·Î½ÃÀúºÎÅÍ ºÐ¼®ÇØ º¸ÀÚ. ÀÌ ´ëÈ»óÀÚÀÇ lParamÀ¸·Î È°¼º ºäÀÇ Æ÷ÀÎÅÍ°¡ Àü´ÞµÇ¹Ç·Î pView ½ºÅÂƽ º¯¼ö¿¡ ±× °ªÀ» ÀúÀåÇØ µÎ¾ú´Ù. ¸®½ºÆ® ¹Ú½º¿¡ ¹ü·Ê ¹®ÀÚ¿À» ä¿ì°í ¹öÆ° ÀÚ¸®¿¡ ¹®ÀÚÇ¥ ÄÁÆ®·ÑÀ» ¹èÄ¡ÇÑ´Ù. °¢ ¹®ÀÚ ¼¿Àº 26*26Å©±â¸¦ °¡Áö¸ç °¡·Î·Î 16°³ ¼¼·Î·Î 6°³ÀÇ ¼¿À» ¹èÄ¡ÇÏ¿´´Ù. °æ°è¼±ÀÇ Æøµµ Æ÷ÇÔÇϱâ À§ÇØ ¹®ÀÚÇ¥ ÄÁÆ®·ÑÀÇ Å©±â¿¡ +2¸¦ Çß´Ù.
¹®ÀÚÇ¥ ÄÁÆ®·ÑÀ» ¹èÄ¡ÇÑ ÈÄ ³ª¸ÓÁö ÄÁÆ®·ÑÀÇ À§Ä¡µµ Àû´çÈ÷ Á¶Á¤ÇÏ°í ´ëÈ»óÀÚ ÀÚüÀÇ Å©±âµµ Á¶Á¤Çß´Ù. ´ëÈ»óÀÚ´Â DLU¶ó´Â Ưº°ÇÑ ´ÜÀ§¸¦ »ç¿ëÇϱ⠶§¹®¿¡ ½Ã½ºÅÛ ÆùÆ® Å©±â¿¡ ¿µÇâÀ» ¹ÞÁö¸¸ ¹®ÀÚÇ¥ ÄÁÆ®·ÑÀº ±×·¸Áö ¸øÇϹǷΠ½Ã½ºÅÛ ÆùÆ® º¯°æ½Ã¿¡µµ ÀÏÁ¤ÇÑ ¸ð¾çÀ» º¸¿© ÁÖ±â À§ÇؼÀÌ´Ù. »ðÀÔ ¹öÆ°À» ´©¸£¸é g_cat¿Í g_nx, g_ny¸¦ ÂüÁ¶ÇÏ¿© ÇöÀç ¼±ÅõǾî ÀÖ´Â ¹®ÀÚ¸¦ È°¼º ºä¿¡ »ðÀÔÇÑ´Ù.
¹®ÀÚÇ¥ ÄÁÆ®·ÑÀº g_cat ¹ü·ÊÀÇ ¹®ÀÚµéÀ» ÀÛ¾÷ ¿µ¿ª¿¡ µµÇ¥ ÇüÅ·Πº¸¿© ÁØ´Ù. g_nx, g_nyÀ§Ä¡ÀÇ ¹®ÀÚ¿¡´Â ¼±Åà ºí·°À» ±×·Á ÁÖ°í ÀÌ ÄÁÆ®·ÑÀÌ Æ÷Ä¿½º¸¦ °¡Áö°í ÀÖÀ¸¸é Æ÷Ä¿½º »ç°¢Çüµµ ±×·È´Ù. Æ÷Ä¿½º¿¡ º¯È°¡ ÀÖÀ» ¶§¸¶´Ù ´Ù½Ã ±×¸°´Ù. °£´ÜÇÑ ÄÁÆ®·ÑÀ̶ó ´õºí ¹öÆÛ¸µÀº ÇÏÁö ¾Ê¾Æ ±ô¹Ú°Å¸²ÀÌ Á¶±Ý ÀÖ´Ù. ¸¶¿ì½º ¹öÆ°À» ´©¸£¸é ´©¸¥ À§Ä¡¸¦ g_nx, g_ny¿¡ ´ëÀÔÇÑ´Ù. PgUp, PgDnÀ» ´©¸£¸é ºÎ¸ð À©µµ¿ì¿¡°Ô ÅëÁö ¸Þ½ÃÁö¸¦ º¸³» ¹ü·Ê ¸®½ºÆ® ¹Ú½º¸¦ °»½ÅÇϵµ·Ï ÇßÀ¸¸ç Ä¿¼ À̵¿Å°¸¦ ´©¸£¸é g_nx, g_ny¸¦ Àû´çÈ÷ Á¶Á¤ÇÏ°í ÇöÀç °¡¸®Å°´Â ¹®ÀÚ°¡ º¯°æµÇ¾úÀ½À» GRID_CHG ÅëÁö ¸Þ½ÃÁö¸¦ º¸³» ¾Ë·Á ÁØ´Ù. ´õºíŬ¸¯Çϸé GRID_DBLCLK ÅëÁö ¸Þ½ÃÁö¸¦ º¸³» ÀÌ ¹®ÀÚ¸¦ »ðÀÔÇÑ´Ù.
´ëÈ»óÀÚ°¡ Á÷Á¢ ¹®ÀÚÇ¥¸¦ ±×¸®°í °ü¸®ÇÏÁö ¾Ê´Â ÀÌÀ¯´Â ´ëÈ»óÀÚ´Â Å°º¸µå ÀÔ·ÂÀ» ¹ÞÀ» ¼ö ¾ø±â ¶§¹®ÀÌ´Ù. Æ÷Ä¿½º¸¦ °¡Áú ¼ö ÀÖ´Â º°µµÀÇ À©µµ¿ì ÄÁÆ®·ÑÀÌ ÇÊ¿äÇÏ´Ù. ¹®ÀÚÇ¥ ÄÁÆ®·ÑÀº WM_GETDLGCODE ¸Þ½ÃÁö¿¡ ´ëÇØ DLGC_WANTARROWS·Î ÀÀ´äÇØ ÀÚ½ÅÀÌ Ä¿¼ À̵¿Å°¸¦ Á÷Á¢ ó¸®ÇÏ°Ú´Ù´Â ÀÇ»ç Ç¥ÇöÀ» ÇÏ¸ç µû¶ó¼ ÀÌ ÄÁÆ®·ÑÀÌ Æ÷Ä¿½º¸¦ °¡Áö°í ÀÖÀ» ¶§ Ä¿¼ À̵¿Å°·Î ¼±Åà ¹®ÀÚ¸¦ º¯°æÇÒ ¼ö ÀÖ´Ù.
void OnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
....
case IDM_EDIT_INSERTSPECIAL:
DialogBoxParam(g_hInst,MAKEINTRESOURCE(IDD_SPECIAL),hWnd,
SpecialDlgProc,(LPARAM)pView);
break;
OnCommand¿¡¼´Â ´ëÈ»óÀÚ¸¦ È£ÃâÇÒ ¶§ lParamÀ¸·Î È°¼º ºäÀÇ Æ÷ÀÎÅ͸¦ ³Ñ°Ü ÁÖ¾ú´Ù. ½ÇÇàÁßÀÇ ¸ð½ÀÀº ´ÙÀ½°ú °°´Ù.
À©µµ¿ìÁîÀÇ Ç¥ÁØ ¹®ÀÚÇ¥¿Í °ÅÀÇ ºñ½ÁÇÑ ¸ð½ÀÀÌ´Ù. ÃæºÐÇÏÁö´Â ¾ÊÁö¸¸ ÀÚÁÖ »ç¿ëÇϴ Ư¼ö¹®ÀÚ Á¤µµ´Â Æí¸®ÇÏ°Ô ÀÔ·ÂÇÒ ¼ö ÀÖ´Ù.
À©µµ¿ìÁî´Â ¹Ù·Î°¡±â(ShortCut)¶ó´Â °ÍÀ» Áö¿øÇϴµ¥ ¹°¸®ÀûÀÎ ÆÄÀÏÀ» °¡¸®Å°´Â ÀÏÁ¾ÀÇ ¸µÅ© ÆÄÀÏÀÌ´Ù. ¹Ù·Î°¡±â ÆÄÀÏÀº ´ë»óü¿Í ¿¬°áµÈ ÆÄÀÏÀ̹ǷΠÀÌ ÆÄÀÏÀ» ¿¸é ´ë»óü¸¦ ¿¾î¾ß ÇÑ´Ù. ±×·¯³ª 1.0Àº ¹Ù·Î°¡±â¸¦ ÀνÄÇÏÁö ¾Ê¾Æ ÀÌ ÆÄÀÏÀ» ¿©´Â ¹ö±×°¡ ÀÖ¾ú´Ù. ´ÙÀ½ ÇÔ¼ö´Â ¹Ù·Î°¡±âÀÇ ´ë»óü¸¦ ã¾Æ ±× °æ·Î¸¦ ¸®ÅÏÇÑ´Ù.
BOOL ResolveShortCut(TCHAR *ShortCut, TCHAR *Path)
{
HRESULT hr;
IShellLink *pSl=NULL;
IPersistFile *pPf=NULL;
WCHAR wszLnkFile[MAX_PATH]={0,};
hr=CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void **)&pSl);
if (FAILED(hr))
return E_FAIL;
hr=pSl->QueryInterface(IID_IPersistFile, (void **)&pPf);
if (SUCCEEDED(hr)) {
MultiByteToWideChar(CP_ACP, 0, ShortCut, -1, wszLnkFile, MAX_PATH);
hr=pPf->Load(wszLnkFile,0);
if (SUCCEEDED(hr)) {
pSl->GetPath(Path,MAX_PATH,NULL,SLGP_UNCPRIORITY);
}
}
if (pPf) pPf->Release();
if (pSl) pSl->Release();
if (SUCCEEDED(hr)) {
return TRUE;
} else {
return FALSE;
}
}
³»ºÎ ÄÚµå´Â ´Ù¼Ò »ý¼ÒÇѵ¥ ¹Ù·Î°¡±âÀÇ Áö¿ø ÁÖüÀÎ ½©ÀÌ COM ¶óÀ̺귯¸®·Î µÇ¾î ÀÖ¾î ½© ¸µÅ© COM °´Ã¼¸¦ »ý¼ºÇÏ°í IPersistFile ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇÑ ÈÄ Load ¸Þ¼Òµå¸¦ È£ÃâÇØ¾ß ´ë»óü¸¦ ãÀ» ¼ö ÀÖ´Ù. ¹Ù·Î °¡±â¿¡´Â ´ë»óü ¿Ü¿¡µµ ¸¹Àº Á¤º¸µéÀÌ ÀÖÀ¸³ª ¿©±â¼´Â °æ·Î¸¸ ÇÊ¿äÇÏ´Ù. OpenFromFile ÇÔ¼ö¸¦ ¼öÁ¤ÇÏ¿© ¹Ù·Î°¡±â´Â ´ë»óü¸¦ ¿µµ·Ï ÇÑ´Ù.
BOOL OpenFromFile(TCHAR *Path, BOOL bReadOnly/*=FALSE*/, BOOL bBrowse/*=FALSE*/)
{
TCHAR Path2[MAX_PATH];
_splitpath(Path,NULL,NULL,NULL,ext);
if (stricmp(ext,".lnk")==0) {
if (ResolveShortCut(Path,Path2)==FALSE) {
return FALSE;
}
} else {
lstrcpy(Path2,Path);
}
....
È®ÀåÀÚ°¡ lnkÀÌ¸é ¹Ù·Î°¡±â°¡ °¡¸®Å°´Â ´ë»óü¸¦ ¿¬´Ù. Path2 Àӽà ¹öÆÛ¸¦ ¸¸µé°í ¿©±â¿¡ ´ë»óü¸¦ ±¸ÇÑ´Ù. Àμö·Î Àü´ÞµÈ Path¸¦ Á÷Á¢ ¼öÁ¤ÇÒ ¼ö ¾ø±â ¶§¹®¿¡ ´ë»óüÀÇ °æ·Î¸¦ Á¶»çÇϱâ À§ÇÑ Àӽà ¹öÆÛ¸¦ »ç¿ëÇß´Ù. ¹Ù·Î°¡±â°¡ ¾Æ´Ï¸é Path2´Â Àμö·Î Àü´ÞµÈ Path¸¦ ´Ü¼øÈ÷ ´ëÀԹ޴´Ù. ÀÌÈÄÀÇ ÄÚµå´Â Path´ë½Å Path2 ÆÄÀÏÀ» ¿¾î¾ß ÇϹǷΠOpenFromFile ÇÔ¼öÀÇ µÚÂÊ¿¡ ÀÖ´Â ¸ðµç Path¸¦ Path2·Î º¯°æÇÑ´Ù.
´ç±ÙÀº Ž»ö±â Æ˾÷ ¸Þ´º¿¡¼ ÀÓÀÇÀÇ ÆÄÀÏÀ» ¿©´Â ±â´ÉÀ» Á¦°øÇÑ´Ù. ´ç±Ù 1.0Àº ÀÌ ±â´ÉÀ» ±¸ÇöÇϱâ À§ÇØ ·¹Áö½ºÆ®¸®ÀÇ *, Áï ¸ðµç È®ÀåÀÚ¸¦ ÀڽŰú ¿¬°áÇÏ´Â ´Ù¼Ò ±Ø´ÜÀûÀÎ ¹æ¹ýÀ» »ç¿ëÇߴµ¥ ÀÌ ¹æ¹ýÀº ¿©·¯ °¡Áö ¸é¿¡¼ ¹Ù¶÷Á÷ÇÏÁö ¾Ê´Ù. ½Ç½À Ãʹݿ¡ ¹Ì¸® ¾ê±âÇß´Ù½ÃÇÇ 2.0Àº Ž»ö±â¿Í ÇÔ²² µ¿ÀÛÇÏ´Â COM °´Ã¼·Î ÀÌ ±â´ÉÀ» Á¦°øÇÑ´Ù. ÀÌ ¹æ¹ýÀÌ Á¤¼®À̸ç ÈξÀ ´õ À¯¿¬ÇÏ´Ù.
COM °´Ã¼¸¦ ¸¸µå´Â ¹æ¹ý¿¡´Â ¿©·¯ °¡Áö°¡ Àִµ¥ ¿©±â¼´Â ÀÛ°í °¡º¿î ATLÀ» »ç¿ëÇÒ °ÍÀÌ´Ù. COM API¸¦ Á÷Á¢ »ç¿ëÇÏ´Â °ÍÀº ³Ê¹« ¾î·Æ°í »ý»ê¼ºµµ ¶³¾îÁö¸ç MFC¸¦ »ç¿ëÇÏ¸é µ¢Ä¡Å« ¶óÀ̺귯¸®°¡ µû¶ó´Ù³à¾ß ÇϹǷΠ´Üµ¶ ½ÇÇà ÆÄÀÏÀÎ ´ç±Ù°ú´Â ¸ÂÁö ¾Ê´Ù. ATLÀº ÀÚµ¿ÈµÈ COM °´Ã¼ »ý¼ºÀ» Áö¿øÇϸ鼵µ °á°ú ÆÄÀÏÀÌ °¡º¿ö¼ ÁÁ´Ù.
ÀÌ ½Ç½ÀÀ» ÇÏ·Á¸é ATL°ú ½© ¶óÀ̺귯¸®¿¡ ´ëÇÑ Àü¹ÝÀûÀÎ ÀÌÇØ°¡ ÇÊ¿äÇѵ¥ ¿©±â¼ ÀÌ·± °ÍµéÀ» ¼³¸íÇÏ´Â °ÍÀº ½Ç½ÀÀÇ ¸ñÀû¿¡µµ ºÎÇÕÇÏÁö ¾Ê°í ºÎÇǵµ Å©¹Ç·Î º°µµÀÇ ¼ÀûÀ» ÂüÁ¶Çϱ⠹ٶõ´Ù. ÀÌÈÄ ATL¿¡ ´ëÇؼ´Â ¾È´Ù°í °¡Á¤ÇÏ°í ½Ç½À °úÁ¤¸¸ °£·«ÇÏ°Ô ±â¼úÇÑ´Ù. COM °´Ã¼¸¦ »ý¼ºÇϱâ À§ÇØ File/New/Projects¿¡¼ ATL COM AppWizard¸¦ ¼±ÅÃÇÏ°í ÇÁ·ÎÁ§Æ® À̸§Àº DgCmd·Î ÁöÁ¤ÇÑ´Ù. ¸ðµç ¿É¼ÇÀ» µðÆúÆ®·Î ¹Þ¾ÆµéÀÌ°í Finish ¹öÆ°À» ´©¸¥´Ù.
Ŭ·¡½º ºäÀÇ Æ˾÷ ¸Þ´º¿¡¼ New ATL Object Ç׸ñ ¼±ÅÃÇϸé ATL °´Ã¼¸¦ »ý¼ºÇÏ´Â ´ëÈ»óÀÚ°¡ ¿¸®´Âµ¥ µðÆúÆ®·Î ¼±ÅõǾî ÀÖ´Â Simple Object¸¦ ¼±ÅÃÇØ µÎ°í Next¹öÆ°À» ´©¸¥´Ù. ¿ÀºêÁ§Æ® µî·Ï Á¤º¸ ´ëÈ»óÀÚ¿¡¼ ShortName¿¡ DgCmdObj¸¦ ÀÔ·ÂÇÏ¸é ³ª¸ÓÁö ¿É¼ÇÀº ÀÚµ¿À¸·Î ÀԷµǴµ¥ µðÆúÆ®°¡ ¹«³ÇϹǷΠ±×´ë·Î ¹Þ¾ÆµéÀδÙ.
¿©±â±îÁö ½Ç½ÀÇÏ¸é ±âº» ÇÁ·ÎÁ§Æ®°¡ ¿Ï¼ºµÇ¾î ÀÖÀ» °ÍÀÌ´Ù. DgCmdObj.h ÆÄÀÏÀ» ¿¾î DgComObj Ŭ·¡½º¸¦ ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÑ´Ù.
// DgCmdObj.h : Declaration of the CDgCmdObj
#ifndef __DGCMDOBJ_H_
#define __DGCMDOBJ_H_
#include "resource.h" // main symbols
#include <shlobj.h>
#include <comdef.h>
/////////////////////////////////////////////////////////////////////////////
// CDgCmdObj
class ATL_NO_VTABLE CDgCmdObj :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CDgCmdObj, &CLSID_DgCmdObj>,
public IDispatchImpl<IDgCmdObj, &IID_IDgCmdObj, &LIBID_DGCMDLib>,
public IShellExtInit,
public IContextMenu
{
private:
TCHAR **Files;
UINT Num;
public:
CDgCmdObj();
~CDgCmdObj();
void FreeFiles();
DECLARE_REGISTRY_RESOURCEID(IDR_DGCMDOBJ)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDgCmdObj)
COM_INTERFACE_ENTRY(IDgCmdObj)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()
// IDgCmdObj
public:
STDMETHOD(Initialize)(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
STDMETHOD(GetCommandString)(UINT, UINT, UINT*, LPSTR, UINT);
STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO);
STDMETHOD(QueryContextMenu)(HMENU, UINT, UINT, UINT, UINT);
};
#endif //__DGCMDOBJ_H_
½© È®Àå¿¡ ÇÊ¿äÇÑ µÎ °³ÀÇ ÀÎÅÍÆäÀ̽º·ÎºÎÅÍ »ó¼Ó¹Þ°í ÀÌ µÎ ÀÎÅÍÆäÀ̽ºÀÇ ¸Þ¼ÒµåµéÀ» ÀçÁ¤ÀÇÇÏ¿´´Ù. ±×¸®°í µ¿ÀÛ¿¡ ÇÊ¿äÇÑ µÎ °³ÀÇ ¸â¹ö¿Í »ý¼ºÀÚ, Æı«ÀÚ, FreeFiles ¸â¹ö ÇÔ¼ö¸¦ ¼±¾ðÇÑ´Ù. ±¸Çö ÆÄÀÏ¿¡´Â ÀÌ ÇÔ¼öµéÀÇ Äڵ带 ÀÛ¼ºÇÑ´Ù.
// DgCmdObj.cpp : Implementation of CDgCmdObj
#include "stdafx.h"
#include "DgCmd.h"
#include "DgCmdObj.h"
#include <atlconv.h> // for ATL string conversion macros
/////////////////////////////////////////////////////////////////////////////
// CDgCmdObj
CDgCmdObj::CDgCmdObj()
{
Files=NULL;
Num=0;
}
CDgCmdObj::~CDgCmdObj()
{
FreeFiles();
}
void CDgCmdObj::FreeFiles()
{
UINT i;
if (Files) {
for (i=0;i<Num;i++) {
free(Files[i]);
}
free(Files);
}
}
HRESULT CDgCmdObj::Initialize (LPCITEMIDLIST pidlFolder,LPDATAOBJECT pDataObj,HKEY hProgID)
{
HDROP hDrop;
UINT i;
FORMATETC fmt={CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stg = {TYMED_HGLOBAL};
// Àü´ÞµÈ ÆÄÀÏ¸í ±¸ÇÔ
if (FAILED(pDataObj->GetData(&fmt, &stg))) {
return E_INVALIDARG;
}
hDrop=(HDROP)GlobalLock(stg.hGlobal);
if (hDrop==NULL) {
return E_INVALIDARG;
}
FreeFiles();
Num=DragQueryFile(hDrop,0xFFFFFFFF,NULL,0);
Files=(TCHAR **)malloc(Num*sizeof(TCHAR *));
for (i=0;i<Num;i++) {
Files[i]=(TCHAR *)malloc(MAX_PATH);
DragQueryFile(hDrop,i,Files[i],MAX_PATH);
}
GlobalUnlock(stg.hGlobal);
ReleaseStgMedium (&stg);
return NOERROR;
}
HRESULT CDgCmdObj::QueryContextMenu (HMENU hmenu, UINT uMenuIndex, UINT uidFirstCmd,
UINT uidLastCmd, UINT uFlags )
{
// ´õºí Ŭ¸¯¿¡ ´ëÇؼ´Â ¾Æ¹« µ¿ÀÛµµ ÇÏÁö ¾Ê´Â´Ù.
if (uFlags & CMF_DEFAULTONLY) {
return MAKE_HRESULT(SEVERITY_SUCCESS,FACILITY_NULL,0);
}
// ¸Þ´º »ðÀÔ
InsertMenu (hmenu,uMenuIndex,MF_BYPOSITION,uidFirstCmd,TEXT("´ç±ÙÀ¸·Î ÆíÁý"));
return MAKE_HRESULT(SEVERITY_SUCCESS,FACILITY_NULL,1 );
}
HRESULT CDgCmdObj::GetCommandString (UINT idCmd,UINT uFlags,UINT* pwReserved,
LPSTR pszName,UINT cchMax)
{
USES_CONVERSION;
LPCTSTR szHelp=_T("´ç±Ù ÅؽºÆ® ÆíÁý±â·Î ÀÌ ÆÄÀÏÀ» ÆíÁýÇÕ´Ï´Ù.");
if (idCmd==0) {
if (uFlags & GCS_HELPTEXT) {
lstrcpynW((LPWSTR)pszName,T2CW(szHelp),cchMax);
} else {
lstrcpynA(pszName,T2CA(szHelp),cchMax);
}
return S_OK;
}
return E_INVALIDARG;
}
HRESULT CDgCmdObj::InvokeCommand(LPCMINVOKECOMMANDINFO pCmdInfo)
{
UINT i;
HWND hDg;
TCHAR InstPath[MAX_PATH];
TCHAR szCommand[MAX_PATH*2];
STARTUPINFO si={0,};
PROCESS_INFORMATION pi;
ATOM hAtom;
if (HIWORD(pCmdInfo->lpVerb))
return E_INVALIDARG;
switch (LOWORD(pCmdInfo->lpVerb )) {
case 0:
SHRegReadString(SHCU,"Software\\Miyoungsoft\\Dangeun\\1.2\\Setting",
"InstPath","",InstPath,MAX_PATH);
for (i=0;i<Num;i++) {
// µð·ºÅ丮´Â Àü´ÞÇÏÁö ¾ÊÀ½
if (GetFileAttributes(Files[i]) & FILE_ATTRIBUTE_DIRECTORY) {
continue;
}
hDg=FindWindow("Dangeun",NULL);
// ½ÇÇàÁßÀÌÁö ¾ÊÀ¸¸é Á÷Á¢ ½ÇÇà½ÃŲ´Ù.
if (hDg==NULL) {
wsprintf(szCommand,"%s \"%s\"",InstPath,Files[i]);
if (CreateProcess(NULL,szCommand,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) {
WaitForInputIdle(pi.hProcess,5000);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
// ½ÇÇàÁßÀ̸é ÆÄÀÏÀ» ¿µµ·Ï ÇÑ´Ù.
} else {
hAtom=GlobalAddAtom(Files[i]);
SendMessage(hDg,WM_USER+1,(WPARAM)hAtom,0);
GlobalDeleteAtom(hAtom);
SetForegroundWindow(hDg);
}
}
return S_OK;
default:
return E_INVALIDARG;
}
}
IShellExtInit ÀÎÅÍÆäÀ̽º´Â Æ˾÷ ¸Þ´º¿Í ÇÁ·ÎÆÛƼ ½ÃÆ®, µå·¡±× ¾Ø µå·Ó Çڵ鷯¸¦ À§ÇÑ ½© È®Àå ±â´ÉÀ» ÃʱâÈÇÏ´Â ÀÎÅÍÆäÀ̽ºÀÌ¸ç ´ÙÀ½ ¸Þ¼Òµå¸¦ °¡Áø´Ù.
HRESULT Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
ÀμöÀÇ Á¤È®ÇÑ Àǹ̴ ½© È®Àå ŸÀÔ¿¡ µû¶ó Á¶±Ý¾¿ ´Ù¸¥µ¥ Æ˾÷ ¸Þ´º È®ÀåÀÇ °æ¿ì¿¡ ´ëÇؼ¸¸ ¾Ë¾Æ º¸ÀÚ. pidlFolder´Â Æ˾÷ ¸Þ´º°¡ ÆîÃÄÁø µð·ºÅ丮ÀÇ IDÀ̸ç pdtobj´Â ¼±ÅÃµÈ ÆÄÀÏÀÇ ¸ñ·ÏÀÌ°í ¸¶Áö¸· Àμö hkeyProgID´Â Æ÷Ä¿½º¸¦ °¡Áø ÆÄÀÏÀÇ ÆÄÀÏ Å¬·¡½º IDÀÌ´Ù. ÀÌ ÀμöµéÀ» ÀÐÀ¸¸é ¾î´À µð·ºÅ丮¿¡¼ ¾î¶² ÆÄÀϵ鿡 ´ëÇØ Æ˾÷ ¸Þ´º°¡ È£ÃâµÇ¾ú´ÂÁö ¾Ë ¼ö ÀÖ´Ù. DgCmd´Â ÀÌ Áß µÎ ¹ø° Àμö pdtobj¸¸ »ç¿ëÇϴµ¥ ÀÌ ¿ÀºêÁ§Æ®ÀÇ GetData ÇÔ¼ö¸¦ È£ÃâÇÏ¸é ¼±ÅÃµÈ ÆÄÀÏ ¸ñ·ÏÀ» °¡Áö´Â hDrop ÇÚµéÀ» ±¸ÇÒ ¼ö ÀÖ°í ÀÌ ÇÚµé·ÎºÎÅÍ ÆÄÀÏÀÇ ¸ñ·ÏÀ» Á¶»çÇÑ´Ù. Á¶»çµÈ ¸ñ·ÏÀº Files ¹è¿¿¡ µ¿ÀûÇÒ´çÇÏ¿© ÀúÀåÇØ ³õ´Â´Ù.
IContextMenu ÀÎÅÍÆäÀ̽º´Â ½© ¿ÀºêÁ§Æ®¿¡ ´ëÇÑ Æ˾÷ ¸Þ´º Ãâ·Â ±â´ÉÀ» Á¦°øÇϴµ¥ ´ÙÀ½ ¼¼ °³ÀÇ ¸Þ¼Òµå¸¦ Á¦°øÇÑ´Ù. ÀÌ ÀÎÅÍÆäÀ̽º¸¦ »ó¼Ó¹Þ´Â ¿ÀºêÁ§Æ®´Â °¢ ¸Þ¼Òµå¿¡¼ ¿ä±¸ÇÏ´Â µ¿ÀÛÀ» ¼öÇàÇØ¾ß ÇÑ´Ù.
ÀÎÅÍÆäÀ̽º |
¼³¸í |
GetCommandString |
Æ˾÷ ¸Þ´º Ç׸ñ¿¡ ´ëÇÑ ¹®ÀÚ¿À» Á¦°øÇÑ´Ù. ÀÌ ¹®ÀÚ¿Àº Ž»ö±âÀÇ »óŶõ¿¡ Ãâ·ÂµÈ´Ù. |
InvokeCommand |
Æ˾÷ ¸Þ´ºÀÇ Ç׸ñÀ» ¼±ÅÃÇßÀ» ¶§ ÀÌ ¸Þ¼Òµå°¡ È£ÃâµÈ´Ù. Ç׸ñ ¼±Åýà ÇÏ°í ½ÍÀº ÀÛ¾÷À» ¿©±â¿¡ ÀÛ¼ºÇÏ¸é µÈ´Ù. |
QueryContextMenu |
Æ˾÷ ¸Þ´º°¡ ÆîÃÄÁú ¶§ È£ÃâµÇ¸ç ÀÌ ¸Þ¼ÒµåÀÇ hmenu Àμö·Î Àü´ÞµÈ ¸Þ´º¿¡ ¿øÇÏ´Â Ç׸ñÀ» »ðÀÔÇÒ ¼ö ÀÖ´Ù. |
DgCmd °´Ã¼´Â Ž»ö±âÀÇ Æ˾÷ ¸Þ´º¿¡ "´ç±ÙÀ¸·Î ÆíÁý" ¸Þ´º Ç׸ñÀ» »ðÀÔÇÏ°í ÀÌ Ç׸ñÀÌ ¼±ÅõǸé ÆÄÀÏ°ú ÇÔ²² ´ç±ÙÀ» ½ÇÇàÇÑ´Ù. ´ç±ÙÀÇ ½ÇÇà °æ·Î´Â ·¹Áö½ºÆ®¸®ÀÇ InstallPath¿¡ ÀúÀåµÇ¾î ÀÖÀ¸¹Ç·Î ÀÌ °æ·ÎÀÇ Dangeun.exe¸¦ ½ÇÇàÇÏ¸é µÈ´Ù. Ž»ö±âÀÇ º¹¼ö°³ÀÇ ÆÄÀÏÀ» ¼±ÅÃÇØ ³õ°í ÇѲ¨¹ø¿¡ ¿ ¼ö Àֱ⠶§¹®¿¡ Æ˾÷ ¸Þ´º°¡ ¿¸± ¶§ ¼±ÅÃµÈ ÆÄÀÏÀÇ ¸ñ·ÏÀ» Files ¹è¿¿¡ ¹Ì¸® Á¶»çÇØ ³õ´Â´Ù. ½ÇÇàÇÒ ¶§´Â ´ç±ÙÀÌ ÀÌ¹Ì ½ÇÇàÁßÀÎÁö º¸°í ½ÇÇàÁßÀÌ ¾Æ´Ï¸é Á÷Á¢ ½ÇÇà½ÃÅ°°í ÀÌ¹Ì ½ÇÇàÁßÀ̸é WM_USER+1 ¸Þ½ÃÁö¿Í ¾ÆÅè¿¡ ÆÄÀϸíÀ» º¸³» ÆÄÀϸ¸ ¿µµ·Ï ÇÏ¿´´Ù.
ÀÌ °´Ã¼°¡ µ¿ÀÛÇÏ·Á¸é ·¹Áö½ºÆ®¸®¿¡ µî·ÏÇØ¾ß ÇÑ´Ù. ¸¶¹ý»ç¿¡ ÀÇÇØ DgCmdObj.rgs¶ó´Â ÆÄÀÏÀÌ ÀÌ¹Ì ¸¸µé¾îÁ® ÀÖ°í ÀÌ ÄÁÆ®·ÑÀ» µî·ÏÇϱâ À§ÇØ ¾î¶² Á¤º¸µéÀ» ·¹Áö½ºÆ®¸®¿¡ ±â·ÏÇØ¾ß ÇÏ´ÂÁö°¡ ±â·ÏµÇ¾î ÀÖ´Ù. Ž»ö±â¿Íµµ ¿¬°áÇØ¾ß ÇϹǷΠÀÌ ÆÄÀÏ¿¡ Ãß°¡ Á¤º¸¸¦ ÀÛ¼ºÇÑ´Ù.
HKCR
{
DgCmd.DgCmdObj.1 = s 'DgCmdObj Class'
{
CLSID = s '{50BB038D-A3E6-4A0F-A008-E876AD7ACF7D}'
}
DgCmd.DgCmdObj = s 'DgCmdObj Class'
{
CLSID = s '{50BB038D-A3E6-4A0F-A008-E876AD7ACF7D}'
CurVer = s 'DgCmd.DgCmdObj.1'
}
NoRemove CLSID
{
ForceRemove {50BB038D-A3E6-4A0F-A008-E876AD7ACF7D} = s 'DgCmdObj Class'
{
ProgID = s 'DgCmd.DgCmdObj.1'
VersionIndependentProgID = s 'DgCmd.DgCmdObj'
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'TypeLib' = s '{86D88C9B-FA02-4CE9-99DA-74C98AB44404}'
}
}
NoRemove *
{
NoRemove ShellEx
{
NoRemove ContextMenuHandlers
{
ForceRemove Dangeun = s '{50BB038D-A3E6-4A0F-A008-E876AD7ACF7D}'
}
}
}
}
*, Áï ¸ðµç ÆÄÀÏ¿¡ ´ëÇØ DangeunÅ°¸¦ ¸¸µé°í DgCmdObj ÄÁÆ®·ÑÀ» ¿¬°áÇÑ´Ù. ÀÌ¿Ü¿¡ 2000/XP¿¡¼ °ü¸®ÀÚ °èÁ¤À¸·Î ·Î±äÇÏÁö ¾ÊÀº »ç¿ëÀÚ¸¦ À§ÇØ ´ÙÀ½ Äڵ尡 Ãß°¡·Î ´õ ÇÊ¿äÇÏ´Ù. DgCmd.cpp¿¡ Äڵ带 Ãß°¡ÇÑ´Ù.
STDAPI DllRegisterServer(void)
{
OSVERSIONINFO osv;
osv.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(&osv);
if (osv.dwPlatformId==VER_PLATFORM_WIN32_NT) {
SHRegWriteString(SHLM,"Software\\Microsoft\\Windows\\CurrentVersion\\"
"Shell Extensions\\Approved","{50BB038D-A3E6-4A0F-A008-E876AD7ACF7D}","");
}
return _Module.RegisterServer(TRUE);
}
/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
OSVERSIONINFO osv;
osv.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(&osv);
if (osv.dwPlatformId==VER_PLATFORM_WIN32_NT) {
SHDeleteValue(SHLM,"Software\\Microsoft\\Windows\\CurrentVersion\\"
"Shell Extensions\\Approved","{50BB038D-A3E6-4A0F-A008-E876AD7ACF7D}");
}
return _Module.UnregisterServer(TRUE);
}
Approved ¼ºêÅ° ¾Æ·¡¿¡ DgCmdObj ÄÁÆ®·ÑÀÇ GUID·Î °ªÀ» »ý¼ºÇÏ°í µ¥ÀÌÅÍ´Â ¾Æ¹« °ÍÀ̳ª ³Ö¾î ³õ±â¸¸ ÇÏ¸é µÈ´Ù. SHDeleteValue ÇÔ¼ö´Â shlwapi.lib¿¡ Á¤ÀǵǾî ÀÖÀ¸¹Ç·Î ÀÌ ¶óÀ̺귯¸®¸¦ ¸µÅ©ÇØ¾ß ÇÑ´Ù. ÀÌ·¸°Ô ¸¸µé¾îÁø DgCmd.dllÀº ¸®¼Ò½º¿¡ ÀÌ¹Ì Æ÷ÇԵǾî ÀÖ´Ù. ´ç±ÙÀº ´Üµ¶ ½ÇÇà ÆÄÀÏÀ̹ǷΠºÎ¼Ó ÆÄÀÏÀ» °¡ÁöÁö ¾Ê±â À§ÇØ ¸®¼Ò½º¿¡ ³Ö¾î µÎ¾úÀ¸¸ç ÇÊ¿äÇÒ ¶§ ÆÄÀÏ·Î ¸¸µé¾î¼ »ç¿ëÇÑ´Ù. Util.cpp¿¡ ´ÙÀ½ ÇÔ¼ö¸¦ Ãß°¡ÇÑ´Ù.
BOOL RegisterSvr(TCHAR *DllName, BOOL bReg)
{
HRESULT (STDAPICALLTYPE * lpDllEntryPoint)(void);
HINSTANCE hLib;
BOOL Result=TRUE;
// DLL ÆÄÀÏÀ» ¸Þ¸ð¸®·Î ÀоîµéÀδÙ.
if (FAILED(OleInitialize(NULL)))
return FALSE;
hLib=LoadLibraryEx(DllName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (hLib < (HINSTANCE)HINSTANCE_ERROR)
return FALSE;
// ¼³Ä¡, ¶Ç´Â ÇØÁ¦ ÇÔ¼öÀÇ ¹øÁö¸¦ ã´Â´Ù.
if (bReg == TRUE) {
(FARPROC&)lpDllEntryPoint = GetProcAddress(hLib, "DllRegisterServer");
} else {
(FARPROC&)lpDllEntryPoint = GetProcAddress(hLib, "DllUnregisterServer");
}
// ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
if (lpDllEntryPoint) {
if (FAILED((*lpDllEntryPoint)()))
Result=FALSE;
} else {
Result=FALSE;
}
FreeLibrary(hLib);
OleUninitialize();
return Result;
}
COM ¼¹ö¸¦ µî·Ï ¶Ç´Â µî·ÏÇØÁ¦ÇÏ´Â ÀϹÝÀûÀÎ À¯Æ¿¸®Æ¼ ÇÔ¼öÀÌ´Ù. DLLÀÌ ½º½º·Î µî·Ï, ÇØÁ¦ÇÒ ¼ö ÀÖ´Â ´É·ÂÀ» °¡Áö°í ÀÖÀ¸¹Ç·Î ÇØ´ç ÇÔ¼ö¸¸ È£ÃâÇÏ¸é µÈ´Ù. Ž»ö±â Æ˾÷ ¸Þ´º¸¦ µî·Ï, ÇØÁ¦ÇÏ´Â ÇÔ¼ö´Â ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÑ´Ù.
void RegisterPopup(BOOL bReg,BOOL bDelete/*=FALSE*/)
{
TCHAR DllPath[MAX_PATH];
HRSRC hRSrc;
DWORD Size;
HGLOBAL hMem;
PVOID ptr;
HANDLE hFile;
DWORD dwWritten;
OSVERSIONINFO osv;
GetSystemDirectory(DllPath,MAX_PATH);
lstrcat(DllPath,"\\DgCmd.dll");
if (bReg) {
// DLL ÆÄÀÏÀÌ ¾øÀ¸¸é ¸®¼Ò½º¿¡¼ ÃßÃâÇؼ ¸¸µç´Ù.
if (_access(DllPath,0) != 0) {
hRSrc=FindResource(g_hInst,MAKEINTRESOURCE(IDR_DLL1),"DLL");
Size=SizeofResource(g_hInst,hRSrc);
hMem=LoadResource(g_hInst,hRSrc);
ptr=LockResource(hMem);
hFile=CreateFile(DllPath,GENERIC_WRITE,0,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
WriteFile(hFile,ptr,Size,&dwWritten,NULL);
CloseHandle(hFile);
}
RegisterSvr(DllPath,TRUE);
} else {
RegisterSvr(DllPath,FALSE);
if (bDelete) {
osv.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(&osv);
if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) {
MoveFileEx(DllPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT |
MOVEFILE_REPLACE_EXISTING);
} else {
WritePrivateProfileString("rename","NUL",DllPath,"Wininit.ini");
}
}
}
}
µî·ÏÇÒ ¶§ ¸®¼Ò½º¿¡¼ DLL ÆÄÀÏÀ» ÃßÃâÇÏ¿© ½Ã½ºÅÛ µð·ºÅ丮·Î º¹»çÇÏ°í µî·ÏÇÑ´Ù. ´ç±Ù ½ÇÇà ÆÄÀÏÀÌ ÀÌ DLLÀ» °¡Áö°í ÀÖÀ¸¹Ç·Î ¹èÆ÷ÇÒ ¶§´Â ½ÇÇà ÆÄÀϸ¸ ¹èÆ÷ÇÏ¸é µÈ´Ù. »ç¿ëÀÚ°¡ Ž»ö±â¿Í ¿¬°á ¿É¼ÇÀ» ¼±ÅÃÇÏ¸é ¾Ë¾Æ¼ DLL ÆÄÀÏÀ» ¸¸µé¾î ¼³Ä¡ ¹× µî·Ï±îÁö ¼öÇàÇÒ °ÍÀÌ´Ù. ¹°·Ð ÀÌ·± º¹ÀâÇÑ ¹æ¹ý ´ë½Å DgCmd.dllÀ» ½ÇÇà ÆÄÀÏ°ú ÇÔ²² ¹èÆ÷ÇÒ ¼öµµ ÀÖ´Ù. ±×·¯³ª ÀÌ·¸°Ô µÇ¸é ¼³Ä¡ ÇÁ·Î±×·¥±îÁö ¸¸µé¾î¾ß ÇÏ°í ±×·¯¸é ¼³Ä¡ ÇØÁ¦ ÇÁ·Î±×·¥±îÁö µ¢´Þ¾Æ ¸¸µé¾î¾ß ÇÏ´Â ¹ø°Å·Î¿òÀÌ ÀÖ´Ù. ´ç±Ù Á¦ÀÛÀÚ´Â ¼³Ä¡ÇÒ ÇÊ¿ä°¡ ¾ø´Â ´Üµ¶ ½ÇÇà ÆÄÀÏÀ» ¾ÆÁÖ ÁÁ¾ÆÇϹǷΠÁ» ¹«¸®ÇÑ ¹æ¹ýÀ» ¾²´õ¶óµµ Dangeun.exe Çϳª¸¸ °¡Áö°íµµ ÆíÁý±â¸¦ ¹Ù·Î ¾µ ¼ö ÀÖ°Ô ¸¸µé¾ú´Ù.
RegisterPopup ÇÔ¼ö´Â 1.0¿¡µµ ÀÖ¾ú´Âµ¥ µðÆúÆ® Àμö bDelete°¡ Ãß°¡µÇ¾ú´Ù. Ž»ö±â ¿¬°á ¿É¼Ç¸¸ ÇØÁ¦ÇÒ ¶§´Â µî·Ï¸¸ Ãë¼ÒÇÏ¸é µÇÁö¸¸ ¼³Ä¡ÇØÁ¦ÇÒ ¶§´Â DLL ÆÄÀϱîÁö °°ÀÌ »èÁ¦ÇØ¾ß ÇÑ´Ù. ±×·¡¼ bDeleteÀμö°¡ TRUEÀ̸é DLL ÆÄÀϱîÁö °°ÀÌ »èÁ¦Çϵµ·Ï ±â´ÉÀ» È®ÀåÇß´Ù. Ž»ö±â°¡ ÀÌ DLLÀ» ÀÌ¹Ì »ç¿ëÇÏ°í ÀÖÀ¸¹Ç·Î DeleteFile ÇÔ¼ö·Î »èÁ¦ÇÒ ¼ö ¾øÀ¸¸ç ´ÙÀ½ ºÎÆÃÇÒ ¶§ »èÁ¦Çϵµ·Ï µî·ÏÇÑ´Ù. ¼³Ä¡ÇØÁ¦ÇÒ ¶§¸¸ ÀÌ Àμö´Â TRUE°¡ µÈ´Ù.
void Uninstall()
{
....
RegisterPopup(FALSE,TRUE);
RearrangePath ÇÔ¼öÀÇ ´ÙÀ½ È£Ãâ¹®Àº ÀÌÁ¦ ºÒÇÊ¿äÇϹǷΠ»èÁ¦ÇÑ´Ù.
void RearrangePath()
{
....
if (Option.bExplorerPopup) {
RegisterPopup(TRUE);
}
1.0¿¡¼´Â ·¹Áö½ºÆ®¸®¿¡ ´ç±ÙÀÇ °æ·Î°¡ ±â·ÏµÇ¾úÀ¸¹Ç·Î ½ÇÇà ÆÄÀÏÀÇ °æ·Î°¡ ¹Ù²î¸é ·¹Áö½ºÆ®¸®ÀÇ °æ·Îµµ ¼öÁ¤ÇØ¾ß Çß¾ú´Ù. ±×·¯³ª ÀÌÁ¦´Â DgCmd.dllÀÌ ·¹Áö½ºÆ®¸®ÀÇ InstPath¿¡¼ ´ç±ÙÀÇ °æ·Î¸¦ ã±â ¶§¹®¿¡ ½ÇÇà ÆÄÀÏÀÇ °æ·Î°¡ ¹Ù²î´õ¶óµµ DLLÀÌ ´ç±ÙÀ» Á¦´ë·Î ãÀ» ¼ö ÀÖ´Ù. ´ç±ÙÀº ½ÃÀÛÇÒ ¶§¸¶´Ù ÀÚ½ÅÀÇ ½ÇÁ¦ °æ·Î¿Í InstPathÀÇ °ªÀ» ºñ±³ÇØ º¸°í Ʋ¸®¸é InstPath¸¦ Ç×»ó ÃֽŠ°æ·Î·Î ¼öÁ¤ÇÑ´Ù.