文件夾變形
各位觀眾,歡迎來到全金屬的編程講座。今天我們講的是文件夾的變形大法。
首先,我們看看這兩個(gè)圖,如圖1所示。
一秒前:
, 一秒后:
圖1
怎么樣?文件夾變成回收站了!不信?雙擊進(jìn)入試試,里面真的是回收站哦。神奇吧!看過本文,你不但能變文件夾為回收站,還可以將它變成各種稀奇古怪的東東!
首先要說明一下原理:在Windows資源管理器中,Desktop.ini和Folder.htt中定義了文件夾的屬性,在Windows 9X下,我們可以在文件夾中建一個(gè)Desktop.ini,并在其中輸入如下代碼:
[.ShellClassInfo]
Clisd=
這樣文件夾就變成了回收站,但是在Windows XP/2003中就失效了。沒關(guān)系,另有辦法:我們對(duì)著文件夾按下F2,改成“×××.”(不要引號(hào)),也變形了吧?!這其實(shí)也改變了文件夾的屬性,效果是一樣的。通過資料知道,這其實(shí)是運(yùn)用了微軟的Active Desktop技術(shù)。下面我們看看如何利用編程實(shí)現(xiàn)它。
系統(tǒng)環(huán)境:Windows Server 2003 Enterprice Eidtion
開發(fā)工具:VC++ 6.0
本程序是用SDK寫的,這篇文章也是給像我這樣的菜菜看的,現(xiàn)在很多學(xué)編程的菜菜們都愛用VB之類的RAD工具或是一頭鉆進(jìn)MFC,以至于編了N年還不知道什么是Windows消息循環(huán),把十分平常的API函數(shù)調(diào)用(如SendMessage,F(xiàn)indWindows之類)奉之為“技巧”。我沒有鄙視的意思,也不是說號(hào)召大家以后都這樣編程,畢竟用SDK開發(fā)太慢了,我只是覺得要想在Windows編程得到較大進(jìn)步,學(xué)習(xí)Win32下的SDK編程是不應(yīng)該省略的,若只會(huì)Click處理事件,而不知道其中IDE到底干了什么,那就會(huì)阻礙你的進(jìn)步了!
下面簡(jiǎn)略說明一下程序流程:
WinMain函數(shù),程序的入口:
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE ,hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
if (-1 == DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, Main_Proc))
{
MessageBox(NULL, "加載對(duì)話框出錯(cuò)!" , "", MB_OK);
// MessageBox函數(shù),彈出一個(gè)預(yù)定義消息框,第一個(gè)參數(shù)是窗體句柄,第2個(gè)參數(shù)是消息正文,第三個(gè)參數(shù)是標(biāo)題,最后是消息框類型,這里是指有一個(gè)確定按鈕的消息框.
}
return 0;
}
這里使用了DialogBox,調(diào)用一個(gè)模式對(duì)話框,作為與用戶的交互窗口.為什么要這樣呢?畢竟在資源文件里做界面比較方便啊,如圖2所示。
圖2
那么來看看Main_Proc吧,它是對(duì)話框的消息處理函數(shù):
BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//BEGIN MESSAGE CRACK
HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog); //初始化的消息
HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand); //發(fā)給控件們的消息
HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose); //關(guān)閉對(duì)話框的消息
//END MESSAGE CRACK
}
return FALSE;
}
這里要重點(diǎn)介紹HANDLE_MSG宏,它可以簡(jiǎn)化你的程序,它在<windowsx.h> 中。說明如下:
#define HANDLE_MSG(hwnd, message, fn) \
case (message): return HANDLE_##message((hwnd),
(wParam), (lParam), (fn))
這個(gè)宏的作用是雙重的:首先它消除了冗長(zhǎng)的Case 語句,這種 Case 語句在標(biāo)準(zhǔn)的WndProc中實(shí)在令人煩惱,再者它使你擺脫必須傳送消息處理函數(shù)返回值的責(zé)任。所以,這里Main_OnInitDialog是WM_INITDIALOG對(duì)應(yīng)的消息處理函數(shù),Main_OnCommand和Main_OnClose也是如此。Main_OnClose很簡(jiǎn)單,就是EndDialog。Main_OnInitDialog代碼如下:
BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
HWND hCombo=GetDlgItem(hwnd,IDC_TYPE) ;//IDC_TYPE是一個(gè)ComboBox的ID,這個(gè)函數(shù)可以取得特定ID的控件的句柄
SendMessage(hCombo,CB_ADDSTRING,0,(LPARAM)"回收站");//第一項(xiàng)
SendMessage(hCombo,CB_ADDSTRING,1,(LPARAM)"控制面板");//第二項(xiàng)
SendMessage(hCombo,CB_ADDSTRING,2,(LPARAM)"計(jì)劃任務(wù)");//第三項(xiàng)
SendMessage(hCombo,CB_SETCURSEL,0,0);//把第一項(xiàng) 回收站 作為默認(rèn)項(xiàng)放進(jìn)Combobox的文本框.
return TRUE;
}
初始化的作用是為下拉列表框加入列表項(xiàng),我這里加了5項(xiàng),指可以偽裝成5種不同的外形。這三種外形的代碼我放到一個(gè)全局?jǐn)?shù)組中:
char DefaultType[5][125]=",//回收站
"",//密閉文件夾
"",//Word文檔
"",//計(jì)劃任務(wù)
"" //控制面板
};
{645FF040-5081-101B-9F08-00AA002F954E} //回收站
{00000306-0000-0000-C000-000000000046} //密閉文件夾
{00020906-0000-0000-C000-000000000046} //Word文檔
{D6277990-4C6A-11CF-8D87-00AA0060F5BF} //計(jì)劃任務(wù)
{21EC2020-3AEA-1069-A2DD-08002B30309D} //控制面板
那么我從哪里找到這些代碼呢?這些東東都在注冊(cè)表的HKEY_CLASSES_ROOT\CLSID\CLSID下,你可以自己去找找已經(jīng)在系統(tǒng)中注冊(cè)的組件ID加到代碼里,為了方便大家,我這里用到了幾個(gè)比較通用的。
Main_OnCommand函數(shù)是處理對(duì)話框控件消息的函數(shù),代碼如下:
void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
HWND hCombo,hEidt;
char path[1024]=,temppath[MAX_PATH]=,type[125];
int nIndex=0;
LPITEMIDLIST pId; //ITEMIDLIST的指針,以后要用
BROWSEINFO binfo=;//開啟瀏覽框用得結(jié)構(gòu)體,初始化為0
switch(id)
{
case IDC_HIDE: //如果是"偽裝"按鈕的消息,即按下"偽裝" 按鈕
hEidt=GetDlgItem(hwnd,IDC_PATH) ; //得到編輯框的句柄
hCombo=GetDlgItem(hwnd,IDC_TYPE) ; //得到組合框的句柄
GetWindowText(hEidt,path,GetWindowTextLength(hEidt)+1); //得到編輯框中的路徑
nIndex =SendMessage(hCombo,CB_GETCURSEL,0,0L); //得到組合框中被選項(xiàng)序號(hào)
strcpy(type,DefaultType[nIndex]); //就使用這一項(xiàng)對(duì)應(yīng)的代碼
if (GetWindowTextLength(hEidt)!=0) //如果路徑不為空
else
//用來偽裝的函數(shù),把參數(shù)傳遞進(jìn)去
SetWindowText(GetDlgItem(hwnd,IDC_PATH),NULL); //清空編輯框
break;
case IDC_BROW: //點(diǎn)擊"瀏覽"按鈕
binfo.lpszTitle= "請(qǐng)選擇文件夾路徑"; //文件夾選取框的標(biāo)題
pId = SHBrowseForFolder(&binfo); //開啟文件夾選取框
if (pId!=0)
break;
case IDC_REC: //來自”還原”按鈕的消息,點(diǎn)擊了"還原"按鈕
hEidt=GetDlgItem(hwnd,IDC_PATH) ;
hCombo=GetDlgItem(hwnd,IDC_TYPE) ;
GetWindowText(hEidt,path,GetWindowTextLength(hEidt)+1);
if (GetWindowTextLength(hEidt)!=0) //如果路徑不為空
else
SetWindowText(GetDlgItem(hwnd,IDC_PATH),NULL); //清空編輯框
break;
case IDC_EXIT: //點(diǎn)擊"離開按鈕"
EndDialog(hwnd, id); //關(guān)掉模態(tài)對(duì)話框
break;
default:
break;
}
}
能看懂吧?Hide和Recover分別是偽裝和復(fù)原的函數(shù):
bool Hide(HWND hwndMain,char *path,char *type)
{
char output[MAX_PATH+1];
sprintf(output,"%s.%s",path,type);//把路徑和偽裝代碼按照原理篇中提到的格式放到output中.
if (output==NULL) //如果為空則退出
{
MessageBox(hwndMain,"路徑意外地為空","錯(cuò)了",MB_OK);
return false;
}
MoveFile(path,output);//用MoveFile函數(shù)改名
MessageBox(hwndMain,"偽裝成功!","OK",MB_OK);
return true;
}
bool Recover(HWND hwndMain,char *path)
{
int i=0;
int pathlen=strlen(path),typelen=strlen(DefaultType[1])+1; //之所以+1是因?yàn)檫€有一個(gè)句號(hào)
char output[MAX_PATH+1] ;
while (i<=pathlen-typelen) //這里是為了去掉后面的偽裝代碼.得到原文件名
if (output==NULL) //如果為空則退出
{
MessageBox(hwndMain,"路徑意外地為空","錯(cuò)了",MB_OK);
return false;
}
output[i]='\0'; //加個(gè)結(jié)束符
MoveFile(path,output);//用MoveFile函數(shù)改回原名
MessageBox(hwndMain,"還原成功!","",MB_OK);
return true;
}
好了,程序做好了,騙騙普通菜鳥還是很好的,我們自己怎么識(shí)別這樣的程序?其實(shí)只要用命令行就可以進(jìn)入回收站了,如圖3所示。之下藏東西方便了!
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。