vc常用代码1

时间:2021-06-23 00:28:43

 

VC常用代码

分类: VC 学习2009-03-07 15:28 1114人阅读 评论(0) 收藏 举报

===========================================================
//注意事项
//先执行OnInitDialog()函数,然后执行构造函数! 
//98下没有新宋体 
//XP下窗口高度加8 
===========================================================
………1,滚动条处理方法
//1,设置范围 
m_spscroll.SetScrollRange(0,200); 
SCROLLINFO si; 
si.cbSize=sizeof(SCROLLINFO); 
si.nPage=100; 
si.fMask=SIF_PAGE;//设置页宽 
m_spscroll.SetScrollInfo(&si); 
//2,处理消息,垂直滚动条加WM_VSCROLL消息,水平加WM_HSCROLL消息 
void CPrintView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 

// TODO: Add your message handler code here and/or call default 
if(pScrollBar->GetDlgCtrlID()==IDC_SCROLLBAR1) 

int nCurrentPos=pScrollBar->GetScrollPos(); 
SCROLLINFO si; 
si.fMask=SIF_PAGE;//取得页宽 
pScrollBar->GetScrollInfo(&si); 
switch(nSBCode) 

case SB_THUMBTRACK://移动滑块 
case SB_THUMBPOSITION: 
pScrollBar->SetScrollPos(nPos); //设置页宽后滚动条的pos会以max/nPage倍数减少,所以在使用时注意把pos值*(max/nPage)能得到原值 
break; 
case SB_LINEUP://点向上小三角 
pScrollBar->SetScrollPos(nCurrentPos-1); 
break; 
case SB_LINEDOWN://点向下小三角 
pScrollBar->SetScrollPos(nCurrentPos+1); 
break; 
case SB_PAGEUP://向上一页 
pScrollBar->SetScrollPos(nCurrentPos-si.nPage); 
break; 
case SB_PAGEDOWN://向下一页 
pScrollBar->SetScrollPos(nCurrentPos+si.nPage); 
break; 


CDialog::OnVScroll(nSBCode, nPos, pScrollBar); {} 

………2,锁定鼠标
bool pOld; 
CRect rt; 
SetForegroundWindow(); 
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,true,&pOld,SPIF_UpdateINIFILE); 
GetWindowRect(rt); 
ClipCursor(rt); 
//加到 LRESULT CLockDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 会有意外的效果

………3,在列表字符前插入一个负数字符以修改乱码
int index=m_list.GetSelectionMark();//在列表字符前插入一个负数字符以修改乱码 
CString cs; 
cs=m_list.GetItemText(index,0); 
char insert_char=-87; 
cs.Insert(0,insert_char); 
m_list.SetItemText(index,0,cs); 

………4,在列表中添加项目最大只能显示259个字符(不含'/0') 
int char_length=cs.GetLength();//cs,ct为CString类对象,是要发到列表框的文本但是可能大于259字节 
while(char_length>259)//如果大于259字节 

ct=cs.Left(259); 
m_list.InsertItem(0,ct);//在列表中添加项目最大只能显示259个字符(不含'/0') 
cs=cs.Right(char_length-259); 
char_length=cs.GetLength(); 

m_list.InsertItem(0,cs);//在列表中添加项目最大只能显示259个字符(不含'/0') 

………5,设置NT窗口的透明度
OSVERSIONINFO osv; 
osv.dwOSVersionInfoSize=sizeof OSVERSIONINFO; 
GetVersionEx(&osv);//取得版本信息 
if(osv.dwPlatformId==VER_PLATFORM_WIN32_NT)//VER_PLATFORM_WIN32_WINDOWS 98 Me用这个宏 

//加入WS_EX_LAYERED扩展属性 
SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE, 
GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000);//如果多次调用下面这个函数设置,这个函数只在一个位置调用一次就行了 
HINSTANCE hInst = LoadLibrary("User32.DLL"); 
if(hInst) 

typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD); 
MYFUNC fun = NULL; 
//取得SetLayeredWindowAttributes函数指针 
fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes"); 
if(fun)fun(this->GetSafeHwnd(),0, 200,//0 ~ 2552); 
FreeLibrary(hInst); 



………6,字体对话框的初始化
LOGFONT lf; 
lf.lfHeight=-35; 
lf.lfCharSet=134; 
lf.lfWeight=400; 
lf.lfOutPrecision=3; 
lf.lfClipPrecision=2; 
lf.lfQuality=1; 
lf.lfPitchAndFamily=2; 
strcpy(lf.lfFaceName,"宋体");//以上初始化为宋体26号字 
CFontDialog cf(&lf);//字体 
cf.m_cf.rgbColors=textcolor;//颜色 

………7,移动没有标题的窗口
//1定义: 
CPoint just_point; 
//2 
void CClockfortecherDlg::OnLButtonDown(UINT nFlags, CPoint point) 

// TODO: Add your message handler code here and/or call default 
just_point=point; 
CDialog::OnLButtonDown(nFlags, point); 

//3 
void CClockfortecherDlg::OnMouseMove(UINT nFlags, CPoint point) 

// TODO: Add your message handler code here and/or call default 
WINDOWPLACEMENT wi; 
GetWindowPlacement(&wi); 
if(nFlags==MK_LBUTTON) 
SetWindowPos(&wndTop,wi.rcNormalPosition.left+(point.x-just_point.x), wi.rcNormalPosition.top+(point.y-just_point.y), 
0,0,SWP_NOSIZE); 
CDialog::OnMouseMove(nFlags, point); 


………8,线程与信号量
//1,定义信号量句柄 
HANDLE event; 
//2,创建信号量 
event=CreateEvent(NULL, TRUE, FALSE, NULL); 
//3,创建线程: 
//1)定义线程函数,格式必须如下,其中lParam为AfxBeginThread的第二个参数值,可强制转化成所需类型 
UINT WorkThreadProc(LPVOID lParam)//必须是 UINT XXX..XXX(LPVOID lParam) 

//代码示例WaitForSingleObject: 
while(1) 
{
//注意,如果线程间要求同步或互斥的时候,要在每一层循环体中加入WaitForSingleObject 
WaitForSingleObject((HANDLE)lParam, INFINITE); 
//WaitForSingleObject的使用方法:第一个为信号量HANDLE,是CreateEvent的返回值,第二个参数为等待的毫秒数(1/1000秒) 
//第二个参数为INFINITE时则一直等待,直到调用SetEvent()设置信号量时函数返回;为数值(如1000)则函数在1秒后返回 
//(即使你没调用SetEvent()设置信号量) 
AfxMessageBox("fuck");//不能用MessageBox()因为这不是在类中了... 
ResetEvent((HANDLE)lParam); 
//重置信号量,以使WaitForSingleObject函数可以继续等待,否则(如果你已经调用过了SetEvent()设置了信号量) 
//WaitForSingleObject函数将会立刻返回 


//2)用AfxBeginThread创建一个WorkThreadProc的线程 
AfxBeginThread(WorkThreadProc,event); 
//4,在主程序需要的地方调用SetEvent()设置信号量启动线程 
SetEvent(event);//或者用WaitForMultipleObjects函数 
static UINT __stdcall WorkThreadProc(void* pThis);
//如果lParam参数为一个对话框的指针,想调用这个对话框的变量或函数那么就得这样定义线程函数,还要将WorkThreadProc改成//Wait_forDlg::WorkThreadProc,这样WorkThreadProc就成为CWait_forDlg类的函数,在这个线程里就可以调用该类的变量了,注意得用_beginthreadex函数创建线程
UINT CWait_forDlg::WorkThreadProc(void * lParam) 

CWait_forDlg *pThis=(CWait_forDlg *)lParam; 
HANDLE hObjects[2]; 
hObjects[0] = pThis->event1; 
hObjects[1]= pThis->event2; 
while(1) 

DWORD dwWait = WaitForMultipleObjects(2,hObjects,TRUE,INFINITE); 
//第一个参数为信号量个数2,第二个为指针,第三个如果为TRUE函数要等待两个信号量都被SetEvent才返回,返回值为最后一个
//SetEvent的WAIT_OBJECT_0+i;而为FALSE则只要有一个被SetEvent就返回,返回值为 WAIT_OBJECT_0+i 即信号量在数组中的位置 
//+WAIT_OBJECT_0 */ 
if (dwWait == WAIT_OBJECT_0) AfxMessageBox("fcuk 1 "); 
//开始ping 
if (dwWait == WAIT_OBJECT_0 + 1) 
AfxMessageBox("fcuk 2"); 
ResetEvent(hObjects[1]); 
ResetEvent(hObjects[0]); 



#include <process.h> /* 调用_beginthread, _endthread 得包涵这个头文件*/ 
_beginthreadex(NULL, 
0, 
WorkThreadProc, 
(void*) this, 
0, 
0); 
//第三种创建线程的方法: 
HANDLE thread; 
DWORD threadrid; //线程ID 
DWORD WINAPI sniff(LPVOID no){} //线程函数这样定义 
thread=CreateThread(NULL, //安全属性 
0, //栈大小 
sniff, //要创建的线程名 
NULL, //参数(一般为调用线程的指针) 
0, //创建标志 
&threadrid); //线程ID 
CloseHandle(thread); 
………9,操作数据库ODBC
//在stdafx.h中加入 #include <afxdb.h> 
//1,用类向导,建立基于CRecordset或CDaoRecordset的新子类,并选择数据源m_setComplete 
//2,添加 
if ( ! m_setComplete . IsOpen () ) // if the recordset isn't already open.. 
m_setComplete . Open (); // open it 
m_setComplete . AddNew (); // begin the add 
m_setComplete . m_strCallsign = strCallsign; // change the recordset members 
m_setComplete . m_strFrequency = strFrequency; 
m_setComplete . m_strCity = strCity; 
m_setComplete . m_strState = strState; 
m_setComplete . m_strInput = strInput; 
m_setComplete . Update (); // complete the add by doing an update 
m_setComplete . Close (); // close the recordset 
//3,修改 
if ( ! m_setComplete . IsOpen () ) // if the recordset isn't already open.. 
m_setComplete . Open (); // open it 
m_setComplete . Edit (); // begin the edit 
m_setComplete . m_strCallsign = strCallsign; // change the recordset members 
m_setComplete . m_strFrequency = strFrequency; 
m_setComplete . m_strCity = strCity; 
m_setComplete . m_strState = strState; 
m_setComplete . m_strInput = strInput; 
m_setComplete . Update (); // complete the add by doing an update 
m_setComplete . Close (); // close the recordset 
//4,删除 
/* 1, DAO 数据库,不是ODBC 
if (!m_setComplete . IsOpen () ) 
m_setComplete . Open (); 
// cycle through the selected listbox elements. 
strRecordIdQuery =CString ("[ID]=")+CString(m_lcRepeaterList.GetItemText(nItemIndex,0)); // put the ID into the query string 
MessageBox(strRecordIdQuery); 
if ( m_setComplete.FindFirst(strRecordIdQuery)) { // looking for this ID in the database, ID is a unique 'autonumber' 
m_setComplete . Delete (); // delete the record 
     m_setComplete . MoveFirst (); // move back to the first record 
m_bRecordsWereDeleted = TRUE; // make a note that we changed the database 
SetDlgItemText ( IDC_Delete_STATUS, "Repeater Deleted From Database" ); // set the status field 
}else{ 
// if we EVER end up here, either the database is in the crapper, or I will have screwed up horribly--been known to happen from time 
//to time , so let's cover our ass-ets just in case. 
AfxMessageBox ( "Internal failure/n/nCannot find selected repeater in database/nor database is corrupted", MB_ICONSTOP ); 

m_setComplete . Close (); // close the database*/ 

/* 1, ODBC 数据库,不是ADO
m_setComplete.m_strFilter="number=200301";//条件查询(where语句) 
if ( ! m_setComplete . IsOpen () ) 
m_setComplete . Open (); 
m_setComplete.Delete(); 
m_setComplete . MoveFirst (); 
m_setComplete . Close (); // close the database 
m_setComplete.m_strFilter="";//清空条件(where语句) 
//查询(where语句) 
m_setComplete.m_strFilter="number=200301"; 
if ( ! m_setComplete . IsOpen () ) 
m_setComplete . Open (); 
m_setComplete . Close (); // close the database 

//不用类向导写连接数据库的程序段,但是我只看明白了连接和查询,不会修改和添加,删除 
//1, 
CDatabase m_dbCust; //定义数据库类对象 
m_dbCust.OpenEx(_T("DSN=MQIS;UID=sa;PWD=1980623")//打开数据库 //数据源名,用户名,密码 ,CDatabase::forceOdbcDialog );//此参数只定是//否打开连接确认对话框 
//MessageBox(m_dbCust.GetDatabaseName()); 取得数据源名 
//m_dbCust.ExecuteSQL("select number from works");测试是否支持SQL语句 
CRecordset cs(&m_dbCust);//定义目录查询对象 
cs.Open( CRecordset::dynaset, 
_T( "select * from works" ) );//打开时执行的SQL语句 
short nFields = cs.GetODBCFieldCount( );//取得字段数,(列数) 
CDBVariant varValue;//定义通用数据类型 
CODBCFieldInfo co;//定义字段信息 
CString cc; 
while( !cs.IsEOF( ) ) 

for( short index = 0; index < nFields; index++ ) 

// do something with varValue 
cs.GetFieldValue(index,varValue);//取得某列的数据, 
//cs.GetFieldValue(index,cc); 也可直接取得由某列的数据直接转化成的文本 
if(varValue.m_dwType==DBVT_LONG)//m_dwType成员用来判断数据类型 
/* m_dwType Union data member 
DBVT_NULL No union member is valid for access. 
DBVT_BOOL m_boolVal 
DBVT_UCHAR m_chVal 
DBVT_SHORT m_iVal 
DBVT_LONG m_lVal 
DBVT_SINGLE m_fltVal 
DBVT_DOUBLE m_dblVal 
DBVT_DATE m_pdate 
DBVT_STRING m_pstring 
DBVT_BINARY m_pbinary 
*/ 

cc.Format("%d",varValue.m_lVal);//m_dwType==DBVT_LONG时为LONG型数据,成员为m_lVal,数值在其中 
MessageBox(cc); 

cs.GetODBCFieldInfo(index,co);//取得字段信息 
/* struct CODBCFieldInfo 

CString m_strName;    字段名 
SWORD m_nSQLType;    SQL数据类型 
UDWORD m_nPrecision; 
SWORD m_nScale; 
SWORD m_nNullability; 
}; 
*/ 
} //for
cs.MoveNext( );//下一个 

cs.Close(); 

………10,显示程序段* 
CString cstr; 
cstr.Format("%d", ); 
MessageBox(cstr); 
if(MessageBox("关闭Windows秘书您可会失去重要的提醒信息,确定要关闭吗?", 
"Windows秘书", 
MB_OKCANCEL|MB_DEFBUTTON2|MB_ICONWARNING)==IDOK) 
MessageBeep(MB_ICONQUESTION); 

………11,注册与卸载OCX控件
//1,函数入口宏定义 
typedef HRESULT (STDAPICALLTYPE *CTLREGPROC)(); 
//2,注册函数 
BOOL RegisterOcx(CString ocxfilename) 

BOOL bResult = FALSE ; 
HMODULE hModule = ::LoadLibrary(ocxfilename) ; 
//获得注册函数地址 
CTLREGPROC DLLRegisterServer = 
(CTLREGPROC)::GetProcAddress(hModule,"DllRegisterServer" ) ; 
if (DLLRegisterServer != NULL) 

HRESULT regResult = DLLRegisterServer() ; 
bResult = (regResult == NOERROR) ; 

::FreeLibrary(hModule) ; 
return bResult ; 

//2,卸载函数 
BOOL UnRegisterOcx(CString ocxfilename) 

BOOL bResult = FALSE ; 
HMODULE hModule = ::LoadLibrary(ocxfilename) ; 
//获得卸载函数地址 
CTLREGPROC DLLUnregisterServer = 
(CTLREGPROC)::GetProcAddress( hModule, "DllUnregisterServer" ) ; 
if (DLLUnregisterServer != NULL) 

HRESULT regResult = DLLUnregisterServer() ; 
bResult = (regResult == NOERROR) ; 

::FreeLibrary(hModule) ; 
return bResult ; 


………12,处理文件拖动
//1 添加 WM_DropFILES 静态消息 
//2 在OnInitDialog()函数中加入 
DragAcceptFiles(TRUE);//允许拖放 
//3 WM_DropFILES 的处理函数为 
void CCXatDemoDlg::OnDropFiles(HDrop hDropInfo) 

unsigned int nFiles=DragQueryFile(hDropInfo,0xFFFFFFFF,NULL,0);//取得拖放的文件总数 
for (unsigned int i=0;i<nFiles;i++)//循环取得文件名 

unsigned int nLen=DragQueryFile(hDropInfo,i,NULL,0)+1;//取得文件名长度 
char *psBuffer=new char[nLen]; 
unsigned int sLen=DragQueryFile(hDropInfo,i,psBuffer,nLen);//取得文件名到psBuffer中,sLen为实际拷贝的字符数 
//To add code here... 
          
delete [] psBuffer; 

DragFinish(hDropInfo);//结束 


………13,设置窗口大小和位置
SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);//设为最高层 
/* 
wndBottom 
wndTop 
wndTopMost 
wndNoTopMost 
*/ 
//在窗体中这样做 HWND_NOTOPMOST 为不是最高层 
::SetWindowPos(AfxGetMainWnd()->m_hWnd,HWND_TOPMOST,-1,-1,-1,-1,SWP_NOMOVE|SWP_NOSIZE); 
/* 
HWND_BOTTOM 
HWND_NOTOPMOST 
HWND_TOP 
HWND_TOPMOST 
SWP_DRAWFRAME Draws a frame, defined in the class description of the window, around the window. 
SWP_FRAMECHANGED Sends a WM_NCCALCSIZE message to the window, even if the size of the window is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the size of the window is being changed. 
SWP_HIDEWINDOW Hides the window. 
SWP_NOACTIVATE Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or nontopmost group, depending on the setting of the hWndInsertAfter parameter. 
SWP_NOMOVE Retains the current position and ignores the X and Y parameters. 
SWP_NOOWNERZORDER Does not change the position in the Z order of the owner window. 
SWP_NOREPOSITION Same as the SWP_NOOWNERZORDER flag. 
SWP_NOSIZE Retains the current size and ignores the cx and cy parameters. 
SWP_NOZORDER Retains the current Z order and ignores the hWndInsertAfter parameter. 
SWP_SHOWWINDOW Displays the window. 
*/ 

………14,在系统栏显示图标
//1定义结构 
NOTIFYICONDATA systemicon; 
//2定义新的消息 
#define WM_SYSTEMMESSAGE WM_USER+998 
//3添加消息函数映射 
ON_MESSAGE(WM_SYSTEMMESSAGE,OnSystemMessage) 
//4初始化结构 
systemicon.cbSize=sizeof(NOTIFYICONDATA); 
systemicon.hWnd=this->m_hWnd; 
systemicon.uID=IDI_SYSICON; //图标 
systemicon.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP; 
systemicon.uCallbackMessage=WM_SYSTEMMESSAGE; 
systemicon.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_SYSICON)); 
strcpy(systemicon.szTip,"Windows秘书"); 
Shell_NotifyIcon(NIM_ADD,&systemicon);//显示 
strcpy(systemicon.szTip,cs); 
Shell_NotifyIcon(NIM_MODIFY,&systemicon);//修改 
Shell_NotifyIcon(NIM_Delete,&systemicon);//删除 
//处理函数 
void OnSystemMessage(WPARAM wParam, LPARAM lParam) 

if(wParam!=IDI_SYSICON) 
return; 
switch(lParam) 

case WM_RBUTTONUP://右键起来时弹出快捷菜单 

CMenu *menu=NULL; 
LPPOINT mousepoint=new tagPOINT; 
::GetCursorPos(mousepoint);//得到鼠标位置 
BCMenu bmpmenu; 
bmpmenu.LoadMenu(IDR_SYSPOPUPMENU); 
menu = bmpmenu.GetSubMenu (0);//确定弹出式菜单的位置 
if (IsWindowVisible()) 
bmpmenu.ModifyODMenuA("隐藏主窗口",ID_SHOWHIDE,IDB_HIDE); 
else 
bmpmenu.ModifyODMenuA("显示主窗口",ID_SHOWHIDE,IDB_SHOW); 
if (findtxdata->stoplowstep==0) 
bmpmenu.ModifyODMenuA("停止普通级提醒",ID_STOPALLPT,IDB_STOP); 
else 
bmpmenu.ModifyODMenuA("启用普通级提醒",ID_STOPALLPT,IDB_NOTSTOP); 
if (topornot) 
bmpmenu.ModifyODMenuA("窗体不在最上层",ID_NOTONTOP,IDB_NOTTOP); 
else 
bmpmenu.ModifyODMenuA("窗体在最上层",ID_NOTONTOP,IDB_TOP); 
if (!muteornot) 
bmpmenu.ModifyODMenuA("静音",IDMUTE,IDB_NOSOUND); 
else 
bmpmenu.ModifyODMenuA("取消静音",IDMUTE,IDB_SOUND); 
SetForegroundWindow();//必须先调用这个函数才能如果我不选择任何菜单而取消它 
menu->TrackPopupMenu(TPM_LEFTALIGN,mousepoint->x,mousepoint->y,this); 
//资源回收 
//menu->Detach(); 
//menu->DestroyMenu(); 
delete mousepoint; 
break; 


return; 


………15,浮动鼠标提示
//1定义 
CToolTipCtrl tooltip; 
//2在OnCreate函数中创建 
tooltip.Create(this); 
//3在OnInitDialog函数中为控件添加提示字符 
tooltip.AddTool(GetDlgItem(IDC_DATEANDTIME),"显示日期/时间"); 
tooltip.Activate(TRUE);//启动 
//4在PreTranslateMessage(MSG* pMsg) 函数中加上 
tooltip.RelayEvent(pMsg); 

………16,tab控件的使用
m_tab.InsertItem(0,"提醒"); 
//定义结构 
WINDOWPLACEMENT wininfo; 
//取得窗口信息 
m_tab.GetWindowPlacement(&wininfo); 
//注意第一个参数要为&wndTop,如果是&wndTopMost就可能会函数功能无效 
qita.SetWindowPos(&wndTop,wininfo.rcNormalPosition.left-10,wininfo.rcNormalPosition.top+20,0,0,SWP_NOSIZE|SWP_HIDEWINDOW); 
//选择不同的标签 
void OnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult) 

// TODO: Add your control notification handler code here 
int i=m_tab.GetCurSel(); 
switch(i) 

case 0: 
break; 
case 1: 
break; 

*pResult = 0; 


………17,注册热键
//m_filehotkey为热键控件变量 
m_filehotkey.GetHotKey(WORD virtualkey,WORD flags); 
//注意要在主窗口中调用这个函数 
void RegHotKey(WORD virtualkey,WORD flags,int id) 

if (flags==1||flags==9)//从热键控件中得到的系统键与下函数的标志不同,但有一一对应的关系: 

RegisterHotKey(GetSafeHwnd(),id,MOD_SHIFT,virtualkey); 
}//每个ID只能注册一个热键,up,down,home,end等中部键盘的键的flags为9,10,11,12,13,14,15 
if (flags==2||flags==10)//其余为1,2,3,4,5,6,7 

RegisterHotKey(GetSafeHwnd(),id,MOD_CONTROL,virtualkey); 

if (flags==4||flags==12) 

RegisterHotKey(GetSafeHwnd(),id,MOD_ALT,virtualkey); 

if (flags==3||flags==11) 

RegisterHotKey(GetSafeHwnd(),id,MOD_CONTROL|MOD_SHIFT,virtualkey); 

if (flags==5||flags==13) 

RegisterHotKey(GetSafeHwnd(),id,MOD_ALT|MOD_SHIFT,virtualkey); 

if (flags==6||flags==14) 

RegisterHotKey(GetSafeHwnd(),id,MOD_ALT|MOD_CONTROL,virtualkey); 

if (flags==7||flags==15) 

RegisterHotKey(GetSafeHwnd(),id,MOD_ALT|MOD_CONTROL|MOD_SHIFT,virtualkey); 


//处理消息 
LRESULT CWindowsDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 

// TODO: Add your specialized code here and/or call the base class 
switch(message) 

case WM_HOTKEY : 
switch(wParam) 

case IDC_HOTKEY: 
if (IsWindowVisible()) 
ShowWindow(SW_HIDE); 
else 
ShowWindow(SW_SHOWNORMAL); 
SetForegroundWindow(); 
break; 
case IDC_HOTKEY2: 
break; 

return 0 ; 

return CDialog::WindowProc(message, wParam, lParam); 


………18,控制系统音量
// 在StdAfx.h中加入宏 
#include <mmsystem.h> 
// 在setting->Link中加入下静态链接库:winmm.lib 
// 播放声音 文件名 风格:第一个参数为文件名/找不到文件时不播放默认声音 
PlaySound( "", NULL, SND_FILENAME |SND_NODEFAULT); 
// 定义结构 
UINT m_nNumMixers; //混合器的数量 
HMIXER m_hMixer; //当前混合器的句柄 
MIXERCAPS m_mxcaps; //当前混合器的性能参数 
CString m_strDstLineName, m_strVolumeControlName; //混合器控件的名称 
DWORD m_dwMinimum, m_dwMaximum; //最大,最小的音量值 
DWORD m_dwVolumeControlID; //混合器控件的音量控制ID 
DWORD m_dwMuteControlID; //混合器控件的静音控制ID 
BOOL muteornot; //是否静音 
DWORD nowvolume; //当前值 
double multiple; 
double difference; //最大最小差值 
int volumestep;//步长 
// 加入消息映射函数 
ON_MESSAGE(MM_MIXM_CONTROL_CHANGE, OnMixerCtrlChange) 
// 当系统音量改变时调用此函数 
LONG OnMixerCtrlChange(UINT wParam, LONG lParam) 

//响应控件音量改变的消息,然后获得当前音量并设置滚动条 
if ((HMIXER)wParam == m_hMixer && (DWORD)lParam == m_dwVolumeControlID) 

amdGetMasterVolumeValue(nowvolume); 
multiple=nowvolume; 
double percent; 

if ((HMIXER)wParam == m_hMixer && (DWORD)lParam == m_dwMuteControlID) 

amdGetMasterMuteValue(muteornot); 

return 0L; 

// 在Init函数中加入 
if (amdInitialize()) 

//获得音量控制控件的ID和名称 
amdGetMasterVolumeControl(); 
// 获得当前音量值,并设置滚动条的初始位置 
amdGetMasterVolumeValue(nowvolume); 
amdGetMasterMuteValue(muteornot); 
multiple=nowvolume; 
difference=(long)(m_dwMaximum-m_dwMinimum); 

// 函数 
BOOL amdInitialize()//初始化 

//获取当前混合设备数量 
m_nNumMixers = ::mixerGetNumDevs(); 
m_hMixer = NULL; 
::ZeroMemory(&m_mxcaps, sizeof(MIXERCAPS)); 
if (m_nNumMixers != 0) 

//打开混合设备 
if (::mixerOpen(&m_hMixer, 
0, 
(DWORD)this->GetSafeHwnd(), 
NULL, 
MIXER_OBJECTF_MIXER | CALLBACK_WINDOW) != MMSYSERR_NOERROR) 
return FALSE; 

// 获取混合器性能 
if  (::mixerGetDevCaps((UINT)m_hMixer, &m_mxcaps, sizeof(MIXERCAPS))!= MMSYSERR_NOERROR) 
return FALSE; 

return TRUE; 

BOOL amdGetMasterVolumeControl()//获得音量控制控件的ID和名称 

m_strDstLineName.Empty(); 
m_strVolumeControlName.Empty(); 
if (m_hMixer == NULL) 
return FALSE; 
//获得混合器性能 
MIXERLINE mxl; 
mxl.cbStruct = sizeof(MIXERLINE); 
mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; 
if (::mixerGetLineInfo((HMIXEROBJ)m_hMixer, 
&mxl, 
MIXER_OBJECTF_HMIXER | 
MIXER_GETLINEINFOF_COMPONENTTYPE)!= MMSYSERR_NOERROR) 
return FALSE; 
MIXERCONTROL mxc; 
MIXERLINECONTROLS mxlc; 
mxlc.cbStruct = sizeof(MIXERLINECONTROLS); 
mxlc.dwLineID = mxl.dwLineID; 
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;//此值表示取得音量 
mxlc.cControls = 1; 
mxlc.cbmxctrl = sizeof(MIXERCONTROL); 
mxlc.pamxctrl = &mxc; 
//获得混合器线控件 
if (::mixerGetLineControls((HMIXEROBJ)m_hMixer, 
&mxlc, 
MIXER_OBJECTF_HMIXER | 
MIXER_GETLINECONTROLSF_ONEBYTYPE)!= MMSYSERR_NOERROR) 
return FALSE; 
//记录控件的信息 
m_strDstLineName = mxl.szName; 
m_strVolumeControlName = mxc.szName; 
m_dwMinimum = mxc.Bounds.dwMinimum; 
m_dwMaximum = mxc.Bounds.dwMaximum; 
m_dwVolumeControlID = mxc.dwControlID; 
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;//此值表示取得静音与否 
if (::mixerGetLineControls((HMIXEROBJ)m_hMixer, 
&mxlc, 
MIXER_OBJECTF_HMIXER | 
MIXER_GETLINECONTROLSF_ONEBYTYPE)!= MMSYSERR_NOERROR) 
return FALSE; 
m_dwMuteControlID = mxc.dwControlID; 
return TRUE; 

BOOL amdGetMasterVolumeValue(DWORD &dwVal)// 获得当前音量值,并设置滚动条的初始位置 

if (m_hMixer == NULL || m_strDstLineName.IsEmpty() || m_strVolumeControlName.IsEmpty()) 
return FALSE; 
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume; 
MIXERCONTROLDETAILS mxcd; 
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); 
mxcd.dwControlID = m_dwVolumeControlID; 
mxcd.cChannels = 1; 
mxcd.cMultipleItems = 0; 
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); 
mxcd.paDetails = &mxcdVolume; 
//获取指定混合器控件 
if (::mixerGetControlDetails((HMIXEROBJ)m_hMixer, 
&mxcd, 
MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR) 
return FALSE; 
dwVal = mxcdVolume.dwValue; 
return TRUE; 

BOOL amdGetMasterMuteValue(BOOL &yorn)//是否静音 

if (m_hMixer == NULL || m_strDstLineName.IsEmpty() || m_strVolumeControlName.IsEmpty()) 
return FALSE; 
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume; 
MIXERCONTROLDETAILS mxcd; 
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); 
mxcd.dwControlID = m_dwMuteControlID; 
mxcd.cChannels = 1; 
mxcd.cMultipleItems = 0; 
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); 
mxcd.paDetails = &mxcdVolume; 
//获取指定混合器控件 
if (::mixerGetControlDetails((HMIXEROBJ)m_hMixer, 
&mxcd, 
MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR) 
return FALSE; 
yorn = mxcdVolume.dwValue; 
return TRUE; 

BOOL amdSetMasterMuteValue(BOOL &yorn)//设置静音与否 

if (m_hMixer == NULL || m_strDstLineName.IsEmpty() || m_strVolumeControlName.IsEmpty()) 
return FALSE; 
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume = { yorn }; 
MIXERCONTROLDETAILS mxcd; 
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); 
mxcd.dwControlID = m_dwMuteControlID; 
mxcd.cChannels = 1; 
mxcd.cMultipleItems = 0; 
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); 
mxcd.paDetails = &mxcdVolume; 
//放置混合器控件 
if (::mixerSetControlDetails((HMIXEROBJ)m_hMixer, 
&mxcd, 
MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR) 
return FALSE; 
return TRUE; 

BOOL amdSetMasterVolumeValue(DWORD dwVal)//设置音量 

if (m_hMixer == NULL || m_strDstLineName.IsEmpty() || m_strVolumeControlName.IsEmpty()) 
return FALSE; 
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume = { dwVal }; 
MIXERCONTROLDETAILS mxcd; 
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); 
mxcd.dwControlID = m_dwVolumeControlID; 
mxcd.cChannels = 1; 
mxcd.cMultipleItems = 0; 
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); 
mxcd.paDetails = &mxcdVolume; 
//放置混合器控件 
if (::mixerSetControlDetails((HMIXEROBJ)m_hMixer, 
&mxcd, 
MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR) 
return FALSE; 
return TRUE; 

BOOL amdUninitialize()//关闭 

BOOL bSucc = TRUE; 
if (m_hMixer != NULL) 

//关闭混合器 
bSucc = ::mixerClose(m_hMixer) == MMSYSERR_NOERROR; 
m_hMixer = NULL; 

return bSucc; 

//在OnDestroy() 中加入 
amdUninitialize(); 

………19,编辑注册表
DWORD disp,valuelength=260; 
HKEY parentkey; 
HKEY childkey; 
char filepath[MAX_PATH]; 
//打开主键 
RegOpenKeyEx(HKEY_LOCAL_MACHINE,"software//microsoft//windows//currentversion//run",//注册启动信息 0L,KEY_WRITE,&parentkey); 
//查询键值 
RegQueryValueEx(parentkey,"Windows秘书",0,NULL,(unsigned char *)filepath,&valuelength); 
//写入键值 
RegSetValueEx(parentkey,"Windows秘书",0,REG_SZ,(const unsigned char *)filepath,strlen(filepath)); 
//删除键值 
RegDeleteValue(parentkey,"Windows秘书"); 
//关闭 
RegCloseKey(parentkey); 
//建立子键 
RegOpenKeyEx(HKEY_LOCAL_MACHINE,"software", 
0L,KEY_WRITE,&parentkey);//打开主键 
RegCreateKeyEx(parentkey,"宇光软件",NULL,"CWindowsDlg",REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, 
NULL,&childkey,&disp);//把子键保存在childkey中 
RegCloseKey(parentkey); 
//在子键中写入子键值 
RegSetValueEx(childkey,"Windows秘书",0,REG_SZ,(const unsigned char *)filepath,strlen(filepath)); 
RegCloseKey(childkey); 

………20,创建桌面快捷图标和创建开始菜单组
//初始化 
CoInitialize (NULL); 
//建立桌面快捷图标函数 
void CreateDesttop(char *filepath) 


strcat(filepath,"//Windows秘书.exe"); 
LPITEMIDLIST pidlBeginAt; 
char szLink[MAX_PATH]="";//快捷方式的数据文件名 
// 取得桌面的PIDL 
SHGetSpecialFolderLocation( HWND_DESKTOP,CSIDL_DESKTOPDIRECTORY, &pidlBeginAt) ; 
// 把PIDL转换为路径名 
SHGetPathFromIDList( pidlBeginAt, szLink) ; 
strcat(szLink,"//Windows秘书.lnk"); 
IShellLink * psl ; 
IPersistFile* ppf ; 
WORD wsz[ MAX_PATH] ; 
//创建一个IShellLink实例 
CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl) ; 
//设置目标应用程序 
psl -> SetPath( filepath) ; 
//设置快捷键(此处设为Shift+Ctrl+'R') 
psl -> SetHotkey( MAKEWORD( 'Q', HOTKEYF_SHIFT |HOTKEYF_CONTROL|HOTKEYF_ALT)) ; 
//从IShellLink获取其IPersistFile接口 
//用于保存快捷方式的数据文件 (*.lnk) 
psl -> QueryInterface( IID_IPersistFile, (void**)&ppf) ; 
// 确保数据文件名为ANSI格式 
MultiByteToWideChar( CP_ACP, 0, szLink, -1, wsz, MAX_PATH) ; 
//调用IPersistFile::Save 
//保存快捷方式的数据文件 (*.lnk) 
ppf -> Save( wsz, STGM_READWRITE) ; 
//释放IPersistFile和IShellLink接口 
ppf -> Release( ) ; 
psl -> Release( ) ; 

SHChangeNotify( SHCNE_Create|SHCNE_INTERRUPT,SHCNF_FLUSH | SHCNF_PATH, szLink,0); 
//取得szPath的父目录 
char* p; 
for( p=szLink+lstrlen(szLink)-1; *p != '//'; p--);
*p='/0'; 
SHChangeNotify(SHCNE_UpdateDIR |SHCNE_INTERRUPT,SHCNF_FLUSH | SHCNF_PATH,szLink,0); 

//创建开始菜单组的函数 
void CWindowsDlg::CreateStarMenu(char *filepath) 

LPITEMIDLIST pidlBeginAt; 
char szPath[ MAX_PATH] ; 
// 取得开始菜单的PIDL 
SHGetSpecialFolderLocation( HWND_DESKTOP, CSIDL_STARTMENU, &pidlBeginAt) ; 
SHGetPathFromIDList( pidlBeginAt, szPath) ;// 把PIDL转换为路径名 
strcat(szPath,"//宇光软件"); 
if( !CreateDirectory( szPath, NULL))return ; 
SHChangeNotify( SHCNE_MKDIR|SHCNE_INTERRUPT, SHCNF_FLUSH | SHCNF_PATH, szPath,0); 
//取得szPath的父目录 
char* p; 
for( p=szPath+lstrlen(szPath)-1;*p != '//'; p--); 
*p='/0'; 
SHChangeNotify(SHCNE_UpdateDIR |SHCNE_INTERRUPT, SHCNF_FLUSH | SHCNF_PATH,szPath,0); 
strcat(filepath,"//Windows秘书.exe"); 
strcat(szPath,"//宇光软件//Windows秘书.lnk"); 
IShellLink * psl ; 
IPersistFile* ppf ; 
WORD wsz[ MAX_PATH] ; 
//创建一个IShellLink实例 
CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl) ; 
//设置目标应用程序 
psl -> SetPath( filepath) ; 
//设置快捷键(此处设为Shift+Ctrl+'Y') 
psl -> SetHotkey( MAKEWORD( 'Y', HOTKEYF_SHIFT |HOTKEYF_CONTROL|HOTKEYF_ALT)) ; 
//从IShellLink获取其IPersistFile接口 
//用于保存快捷方式的数据文件 (*.lnk) 
psl -> QueryInterface( IID_IPersistFile, (void**)&ppf) ; 
// 确保数据文件名为ANSI格式 
MultiByteToWideChar( CP_ACP, 0, szPath, -1,wsz, MAX_PATH) ; 
//调用IPersistFile::Save 
//保存快捷方式的数据文件 (*.lnk) 
ppf -> Save( wsz, STGM_READWRITE) ; 
//释放IPersistFile和IShellLink接口 
ppf -> Release( ) ; 
psl -> Release( ) ; 

SHChangeNotify( SHCNE_Create|SHCNE_INTERRUPT, SHCNF_FLUSH | SHCNF_PATH, szPath,0); 
//取得szPath的父目录 
for( p=szPath+lstrlen(szPath)-1; *p != '//'; p--); 
*p='/0'; 
SHChangeNotify(SHCNE_UpdateDIR |SHCNE_INTERRUPT, SHCNF_FLUSH | SHCNF_PATH,szPath,0); 

void OnDestroy() 

CoUninitialize();