以下為摘錄:
1、實現開機自運行
我在csdn網站上經常看到有人問這樣的問題,其實要實現開機時就自動運行自己的程式並不難。在註冊表的HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run鍵下可以看到有一系列索引值,它們都是開機自動啟動並執行軟體的路徑。那麼我們要做的就是編程實現將我們的程式的路徑也添加到這個索引值下,就搞定了。著名的“windows最佳化大師”也就是用去掉不必要的開機運行軟體這個方法來實現開機速度最佳化的。
既然要讀寫註冊表,就要用到兩個重要的操作註冊表的函數:RegOpenKey()和RegSetValueEx()。前者用於開啟註冊表的鍵,後者則為開啟的鍵設定索引值,至於這兩個API函數的具體參數,請參見MSDN。為了代碼重用的要求,我為此封裝了一個專門的函數,如下所示:
BOOL SetAutoRun(CString strPath)//開機自動運行
{
CString str;
HKEY hRegKey;
BOOL bResult;
str=_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
if(RegOpenKey(HKEY_LOCAL_MACHINE, str, &hRegKey) != ERROR_SUCCESS)
bResult=FALSE;
else
{
_splitpath(strPath.GetBuffer(0),NULL,NULL,str.GetBufferSetLength(MAX_PATH+1),NULL);
strPath.ReleaseBuffer();
str.ReleaseBuffer();
if(::RegSetValueEx( hRegKey,
str,
0,
REG_SZ,
(CONST BYTE *)strPath.GetBuffer(0),
strPath.GetLength() ) != ERROR_SUCCESS)
bResult=FALSE;
else
bResult=TRUE;
strPath.ReleaseBuffer();
}
return bResult;
}
其中strPath參數表示要設定為自啟動並執行程式的絕對路徑。當設定成功時返回true,否則返回false。
這裡又帶來一個問題:既然需要本程式的絕對路徑,那麼怎麼得到它呢?總不能指定一個值吧,那麼當本程式的路徑改變時就又要修改程式,太麻煩了。可以用這個封裝的函數來實現:
//得到程式檔案本身的路徑(包括檔案名稱)
CString GetMyPath()
{
CString strPath;
GetModuleFileName(NULL,strPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);
strPath.ReleaseBuffer();
return strPath;
}
其中GetModuleFileName()是一個得到路徑的API函數。本函數將這個API函數封裝在其中,為的是簡化調用的目的。
當執行這個函數時,返回本程式所在的絕對路徑,包括本程式的檔案名稱。
好了,得到本程式的路徑,然後將它載入到註冊表中,下次系統啟動時,我們的程式就能自動隨之啟動了。
2、實現運行時自動隱藏
這是一個很有趣很古老的話題,csdn上經常有人為此討論不休,提出不少方案,
比如在對話方塊的OnInitDialog()中添加一句:ShowWindow(SW_HIDE);,
或者在對話方塊屬性框中去掉對話方塊的Visible屬性;或者將對話方塊移到案頭以外的地方去;
或者首先將對話方塊最小化,然後實現最小化時隱藏……有趣的是這些很容易想到的常規方法都不能解決這個問題,
或者說解決的不夠好。
我通過尋找相關文章和多次修改代碼,找出了真正解決這個問題的辦法。
之所以用ShowWindow()函數失效,我認為可能是對話方塊的DoModal()在作怪,這麼一來就只能繞開DoModal(),那麼就自然想到可以把對話方塊變成一個無強制回應對話方塊。無強制回應對話方塊平時我們用到的不多,它與強制回應對話方塊不同,是用Create方法Create出來的,而不是DoModal()建立的。
假設建立一個VC.NET工程GetTime,首先在CGetTimeApp類中添加一個成員變數:CGetTimeDlg *dlg;然後在InitInstance()中將原來的:
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
以及return FALSE;全部刪除掉,改為: dlg=new CGetTimeDlg;
m_pMainWnd = dlg;
return dlg->Create(IDD_GETTIME_DIALOG);
最後別忘了在ExitInstance()中加上一句:delete dlg;
好了,這下把本程式的對話方塊變成了一個無強制回應對話方塊。不過既然是無強制回應對話方塊,就不能再用OnOK(),OnCancel()來退出了,要用DestroyWindow()。
由於在上面的代碼中沒有將對話方塊設為可見,所以運行時就實現了隱藏,而且在Windows工作列上也沒有顯示。
至此,第二個問題得到完美解決。