windows(nt/2000)下有很多服務程式(它們在系統登入前執行),它們一般都沒有介面,我們可以在服務管理器(執行services.msc)中啟動和關閉它們。下面我試著修改乙個有介面的mfc對話方塊程式,使它成為乙個服務程式。網上提到了一種方法就是,從建立乙個com服務程式入手,然後將乙個mfc專案改造成服務程式,最後讓這一程式在啟動時可以顯示圖形介面。這種方法的優點就是,程式嚮導已經幫我們寫好了服務程式的主要**,我們的任務就是把它們移植到mfc程式中(這個方法很不錯!)。我的方法和這種方法思想基本一致,但也不完全一樣。我是直接將有些寫在cui服務程式中的**移植過來。主要思想就是把主服務函式等定義為全域性函式,這樣在主對話方塊類中就可以訪問它們了。
此程式需要注意的地方:
一次只能安裝乙個服務,如果已安裝過乙個服務,先將其解除安裝再安裝其他服務,設定其他應用程式時,在scm啟動後,因沒有相應啟動請求會被kill掉。本來以為任何程式都可以被設定為服務程式,後來實驗發現,一般的應用程式被設定為服務程式後,由於它不能夠與scm進行通訊,所以scm無法將其啟動。錯誤提示如下:(下面wcdj是我的服務名字)
本地計算機無法啟動wcdj服務
錯誤1053:服務沒有及時響應啟動或控制請求
這個服務程式的主要流程如下:
service_table_entry dispatchtable=,};
if (!startservicectrldispatcher(dispatchtable))
else if (nresponse == idcancel)}
否則程式會執行**函式:
void winapi servicemain(dword argc, lptstr *argv)
else if (nresponse == idcancel)
...} }
具體的細節看下面的步驟,主要步驟如下:
(1)首先生成乙個基於對話方塊的應用程式框架,假設我的工程名稱為test。
(2)在test.cpp中新增幾個全域性變數和幾個全域性函式。
//設定兩個全域性變數
service_status m_servicestatus;
service_status_handle m_servicestatushandle;
//新增幾個全域性函式
////函式宣告
void winapi servicemain(dword argc, lptstr *argv);
void winapi servicectrlhandler(dword opcode);
bool installservice(cstring &strpath);
bool deleteservice(); //
//函式定義
void winapi servicemain(dword argc, lptstr *argv)
m_servicestatus.dwcurrentstate = service_running;
m_servicestatus.dwcheckpoint = 0;
m_servicestatus.dwwaithint = 0;
if (!setservicestatus (m_servicestatushandle, &m_servicestatus))
//brunning=true;
//while(brunning)
while(1)
else if (nresponse == idcancel)
exit(0);//後面退出不了,只能強行退出
}#ifdef _temp_delete//使用下面**,只能關閉對話方塊不能關閉程式
//關閉對話方塊用,傳遞訊息
msg msg;
while (getmessage(&msg, 0, 0, 0))
dispatchmessage(&msg);
}#endif}
return; }
void winapi servicectrlhandler(dword opcode)
return; }
bool installservice(cstring &strpath)//無法建立其他應用程式為服務,因為它們不能響應啟動請求
;handle schscmanager,schservice;
// getcurrentdirectory(1024,strdir);
// strcat(strdir,"
//test.exe
");
schscmanager = openscmanager(null,null,sc_manager_all_access);
if (schscmanager == null)
return false;
//lpctstr lpszbinarypathname=strdir;
lpctstr lpszbinarypathname;
if (strpath=="")
else
schservice = createservice(schscmanager,"service1","wcdj",// service name to display
service_all_access, // desired access
service_win32_own_process|service_interactive_process, // service type
//service_demand_start, // start type
service_auto_start, //系統啟動時自動啟動
service_error_normal, // error control type
lpszbinarypathname, // service's binary
null, // no load ordering group
null, // no tag identifier
null, // no dependencies
null, // localsystem account
null); // no password
if (schservice == null)
return false;
closeservicehandle(schservice);
return true;}
bool deleteservice()
//在別處顯示對話方塊
// ctestdlg dlg;
// m_pmainwnd = &dlg;
// int nresponse = dlg.domodal();
// if (nresponse == idok)
//
// else if (nresponse == idcancel)
//
//啟動服務(兩種方式:雙擊執行和scm啟動,執行流程如剛開始提到的那樣),對話方塊在下面顯示
service_table_entry dispatchtable=,};
//startservicectrldispatcher(dispatchtable);
if (!startservicectrldispatcher(dispatchtable))
else if (nresponse == idcancel)}
再在上面宣告全域性函式:
extern void winapi servicemain(dword argc, lptstr *argv);
void ctestdlg::onbutton1() //安裝服務
else}
void ctestdlg::onbutton2() //刪除服務
else}
void ctestdlg::onbutton3() //開啟服務管理器
void ctestdlg::onbutton4() //顯示啟動項
最後別忘了在開頭宣告全域性函式:
extern void winapi servicectrlhandler(dword opcode);
extern bool installservice(cstring &strpath);
extern bool deleteservice();
這個服務程式還不是很完善,應該再新增一些判斷和logevent記錄資訊,但是主要的服務程式框架應該都包含了。
最後,希望讀到此篇文章的朋友提出自己的意見。 :)
MFC基於對話方塊程式
001 020 else if nresponse idcancel 如果對話方塊是用取消來關閉的,則 021 025 026 由於對話方塊已關閉,所以將返回 false 以便退出應用程式,027 而不是啟動應用程式的訊息幫浦。028 return false 029 因為initinstance ...
隱藏基於對話方塊的MFC應用程式視窗的方法
很多人可能會將視窗建立出來,然後用乙個 showwindow sw hide 的方法去隱藏視窗,當然這是可以做到隱藏的功能,但是有一點不足的地方就是視窗在隱藏之前會有一下短瞬的閃爍,而以下這種方法可以解決這種問題 c dlg dlg m pmainwnd dlg int nresponse dlg....
MFC 對話方塊程式 模式對話方塊與非模式對話方塊
一 根據主視窗型別,mfc軟體工程可以分為以下幾種架構模型 例如 記事本和畫筆等。2 mdi multiple document inte ce 多文件介面,乙個主框架視窗下可以同時編輯多份文件。例如 vc 6.0,photoshop等軟體。3 基於對話方塊的軟體模型 主視窗是通過資源管理器,在對話...