HKEY hKey; char szFileName[256]; GetModuleFileName(NULL,szFileName,256); RegOpenKey(HKEY_LOCAL_MACHINE,”SOFTWARE\Microsoft\windows\currentversion\run”,&hKey;); if(m_bAutoRun) { RegSetValueEx(hKey,”RunmeAtStartup”,0,REG_SZ,(BYTE *)szFileName,sizeof(szFileName)); } else { RegDeleteValue(hKey,”RunmeAtStartup”); } RegCloseKey(hKey);
动态加载并显示图片
HBITMAP hbitmap=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),”**.bmp”, IMAGE_BITMAP,0,0, LR_CREATEDIBSECTION|LR_LOADFROMFILE); if(hbitmap==NULL) return FALSE; CBitmap m_bitmap; m_bitmap.Attach(hbitmap); HBITMAP hbitmap; //先用上面的方法动态的装载位图,然后把图片显示到Static控件上 //获得指向静态控件的指针 CStatic *pStatic=(CStatic *)GetDlgItem(IDC_SHOWBMP); //获得位图句柄 HBITMAP Bitmap; //设置静态控件的样式,使其可以使用位图,并试位标显示使居中 pStatic->ModifyStyle(0xF,SS_BITMAP|SS_CENTERIMAGE); //设置静态控件显示位图 pStatic->SetBitmap(hBitmap);
ADO如何取得数据库中表的表名
_variant_t vFieldValue; CString strFieldValue; m_pRs=m_pConnection->OpenSchema(adSchemaTables); while(VARIANT_FALSE==m_pRs->IsEOF) { strFieldValue=(char*)_bstr_t(m_pRs->GetCollect(“TABLE_TYPE”)); if(!strcmp(strFieldValue.GetBuffer(0),”TABLE”)||!strcmp(strFieldValue.GetBuffer(0),”table”)) { strFieldValue.ReleaseBuffer(); strFieldValue=(char*)_bstr_t(m_pRs->GetCollect(“TABLE_NAME”)); m_ctlList.AddString(strFieldValue); ///把所有的表名加到控件 } m_pRs->MoveNext(); } m_pRs->Close();
用API实现繁体简体的转换
输入Big5字符,返回Gb简体字符 //————————————————————————— //函数输入Big5字符,返回Gb简体字符 //————————————————————————— AnsiString __fastcall Big2Gb(AnsiString sBig) { char* pszBig5=NULL; //Big5编码的字符 wchar_t* wszUnicode=NULL; //Unicode编码的字符 char* pszGbt=NULL; //Gb编码的繁体字符 char* pszGbs=NULL; //Gb编码的简体字符 AnsiString sGb; //返回的字符串 int iLen=0; //需要转换的字符数
pszBig5=sBig.c_str(); //读入需要转换的字符参数
//计算转换的字符数 iLen=MultiByteToWideChar (950, 0, pszBig5, -1, NULL,0) ; //给wszUnicode分配内存 wszUnicode=new wchar_t[iLen+1]; //转换Big5码到Unicode码,使用了API函数MultiByteToWideChar MultiByteToWideChar (950, 0, pszBig5, -1, wszUnicode,iLen);
//计算转换的字符数 iLen=WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, NULL,0, NULL, NULL) ; //给pszGbt分配内存 pszGbt=new char[iLen+1]; //给pszGbs分配内存 pszGbs=new char[iLen+1]; //转换Unicode码到Gb码繁体,使用API函数WideCharToMultiByte WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, pszGbt,iLen, NULL, NULL) ;
//转换Gb码繁体到Gb码简体,使用API函数LCMapString LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE, pszGbt, -1, pszGbs, iLen);
//返回Gb码简体字符 sGb=pszGbs;
//释放内存 delete [] wszUnicode; delete [] pszGbt; delete [] pszGbs;
return sGb; }
输入Gb字符,返回Big5字符 //————————————————————————— //函数输入Gb字符,返回Big5字符 //————————————————————————— AnsiString __fastcall Gb2Big(AnsiString sGb) { char* pszGbt=NULL; //Gb编码的繁体字符 char* pszGbs=NULL; //Gb编码的简体字符 wchar_t* wszUnicode=NULL; //Unicode编码的字符 char* pszBig5=NULL; //Big5编码的字符 AnsiString sBig5; //返回的字符串 int iLen=0; //需要转换的字符数
pszGbs=sGb.c_str(); //读入需要转换的字符参数
//计算转换的字符数 iLen=MultiByteToWideChar (936, 0, pszGbs, -1, NULL,0) ;
//给pszGbt分配内存 pszGbt=new char[iLen2+1]; //转换Gb码简体到Gb码繁体,使用API函数LCMapString LCMapString(0x0804,LCMAP_TRADITIONAL_CHINESE, pszGbs, -1, pszGbt, iLen2);
//给wszUnicode分配内存 wszUnicode=new wchar_t[iLen+1]; //转换Gb码到Unicode码,使用了API函数MultiByteToWideChar MultiByteToWideChar (936, 0, pszGbt, -1, wszUnicode,iLen);
//计算转换的字符数 iLen=WideCharToMultiByte (950, 0, (PWSTR) wszUnicode, -1, NULL,0, NULL, NULL) ; //给pszBig5分配内存 pszBig5=new char[iLen+1]; //转换Unicode码到Big5码,使用API函数WideCharToMultiByte WideCharToMultiByte (950, 0, (PWSTR) wszUnicode, -1, pszBig5,iLen, NULL, NULL) ;
//返回Big5码字符 sBig5=pszBig5;
//释放内存 delete [] wszUnicode; delete [] pszGbt; delete [] pszBig5;
return sBig5; }
动态加载位图
void CCreateRandomBMPDlg::OnBtnTest() { // TODO: Add your control notification handler code here HBITMAP hBmp;
CFileDialog dlg(TRUE, "bmp", NULL, 0, "位图文件 (*.bmp)|*.bmp||", this);
if (dlg.DoModal() != IDOK)
{
return;
}
hBmp = (HBITMAP) LoadImage(NULL, dlg.GetPathName(), IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (hBmp == NULL)
{
return;
}
BITMAP bm;
PBITMAPINFO bmpInf;
if (GetObject(hBmp, sizeof(bm), &bm;) == 0)
return ;
int nPaletteSize = 0;
if (bm.bmBitsPixel < 16)
nPaletteSize = (int) pow(2, bm.bmBitsPixel);
bmpInf = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize);
//-----------------------------------------------
bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInf->bmiHeader.biWidth = bm.bmWidth;
bmpInf->bmiHeader.biHeight = bm.bmHeight;
bmpInf->bmiHeader.biPlanes = bm.bmPlanes;
bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel;
bmpInf->bmiHeader.biCompression = BI_RGB;
bmpInf->bmiHeader.biSizeImage = (bm.bmWidth + 7) /
8 * bm.bmHeight * bm.bmBitsPixel;
bmpInf->bmiHeader.biXPelsPerMeter = 0;
bmpInf->bmiHeader.biYPelsPerMeter = 0;
bmpInf->bmiHeader.biClrUsed = 0;
bmpInf->bmiHeader.biClrImportant = 0;
//-----------------------------------------------
HDC hDC = ::GetWindowDC(NULL);
if (!::GetDIBits(hDC, hBmp, 0, (WORD) bm.bmHeight, NULL, bmpInf,
DIB_RGB_COLORS))
{
LocalFree(bmpInf);
::ReleaseDC(NULL, hDC);
return ;
}
void* buf = (void*) new char[bmpInf->bmiHeader.biSizeImage];
if (buf == NULL)
{
::ReleaseDC(NULL, hDC);
LocalFree(bmpInf);
return ;
}
if (!::GetDIBits(hDC, hBmp, 0, (UINT) bm.bmHeight, buf, bmpInf,
DIB_RGB_COLORS))
{
::ReleaseDC(NULL, hDC);
delete[]buf;
LocalFree(bmpInf);
return ;
}
::ReleaseDC(NULL, hDC);
CString sMsg;
sMsg.Format("BitsPixel:%d,width:%d,height:%d", bm.bmBitsPixel, bm.bmWidth,
bm.bmHeight);
AfxMessageBox(sMsg);
CClientDC dc(this);
if (bm.bmBitsPixel == 8)
{
BYTE* pData = (BYTE*) buf;
int nWidth = bm.bmWidth;
while (nWidth % 4 != 0)
{
//Bmp每行数据都是4个字节的整数倍。
nWidth++;
}
for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
RGBQUAD rgbQ;
rgbQ = bmpInf->bmiColors[pData[i * nWidth + j]];
dc.SetPixel(j, bm.bmHeight - i,
RGB(rgbQ.rgbRed, rgbQ.rgbGreen, rgbQ.rgbBlue));
}
}
}
else if (bm.bmBitsPixel == 16)
{
BYTE* pData = (BYTE*) buf;
int nWidth = bm.bmWidth*2;
while (nWidth % 4 != 0)
{
nWidth++;
}
BYTE red, green, blue;
for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
blue = pData[i * nWidth + j * 2] & 0x1F;
green = pData[i * nWidth + j * 2] >> 5;
green |= (pData[i * nWidth + j * 2 + 1] & 0x03) << 3;
red = (pData[i * nWidth + j * 2 + 1] >> 2) & 0x1F;
WORD wRed = red*8;
WORD wBlue = blue*8;
WORD wGreen = green*8;
red = min(255, wRed);
blue = min(255, wBlue);
green = min(255, wGreen);
dc.SetPixel(j, bm.bmHeight - i, RGB(red, green, blue));
}
}
}
else if (bm.bmBitsPixel == 24)
{
BYTE* pData = (BYTE*) buf;
int nWidth = bm.bmWidth*3;
while (nWidth % 4 != 0)
{
nWidth++;
}
for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
dc.SetPixel(j, bm.bmHeight -
i,
RGB(pData[i * nWidth + j * 3 + 2],
pData[i * nWidth + j * 3 + 1],
pData[i * nWidth + j * 3]));
}
}
}
else if (bm.bmBitsPixel == 32)
{
BYTE* pData = (BYTE*) buf;
int nWidth = bm.bmWidth*4;
for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
dc.SetPixel(j, bm.bmHeight -
i,
RGB(pData[i * nWidth + j * 4 + 2],
pData[i * nWidth + j * 4 + 1],
pData[i * nWidth + j * 4]));
}
}
}
delete[]buf;
DeleteObject(hBmp);
LocalFree(bmpInf);
}
ADO连接SQL的一般过程
void ADOConn::OnInitADOConn() { ::CoInitialize(NULL); // 初始化OLE/COM库环境 ,为访问ADO接口做准备
try { // 创建Connection对象 m_pConnection.CreateInstance(“ADODB.Connection”); // 设置连接字符串,必须是BSTR型或者_bstr_t类型 _bstr_t strConnect = “Provider=SQLOLEDB; Server=flyspider;Database=HrSys; uid=sa; pwd=;”; m_pConnection->Open(strConnect,””,””,adModeUnknown); } // 捕捉异常 catch(_com_error e) { // 显示错误信息 AfxMessageBox(e.Description()); } }
// 执行查询 _RecordsetPtr& ADOConn::GetRecordSet(_bstr_t bstrSQL) { try { // 连接数据库,如果Connection对象为空,则重新连接数据库 if(m_pConnection==NULL) OnInitADOConn(); // 创建记录集对象 m_pRecordset.CreateInstance(__uuidof(Recordset)); // 取得表中的记录 m_pRecordset->Open(bstrSQL,m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText); } // 捕捉异常 catch(_com_error e) { // 显示错误信息 AfxMessageBox(e.Description()); } // 返回记录集 return m_pRecordset; }
// 执行SQL语句,Insert Update _variant_t BOOL ADOConn::ExecuteSQL(_bstr_t bstrSQL) { //_variant_t RecordsAffected; try { // 是否已经连接数据库 if(m_pConnection == NULL) OnInitADOConn(); // Connection对象的Execute方法:(_bstr_t CommandText, // VARIANT * RecordsAffected, long Options ) // 其中CommandText是命令字串,通常是SQL命令。 // 参数RecordsAffected是操作完成后所影响的行数, // 参数Options表示CommandText的类型:adCmdText-文本命令;adCmdTable-表名 // adCmdProc-存储过程;adCmdUnknown-未知 m_pConnection->Execute(bstrSQL,NULL,adCmdText); return true; } catch(_com_error e) { AfxMessageBox(e.Description()); return false; } }
void ADOConn::ExitConnect() { // 关闭记录集和连接 if (m_pRecordset != NULL) m_pRecordset->Close(); m_pConnection->Close(); // 释放环境 ::CoUninitialize(); }
截获系统注销时候的消息
使用WH_CALLWNDPROC类型钩子,回调函数如下:
LRESULT CALLBACK MyProc(int code, WPARAM wParam, LPARAM lParam) { switch (((CWPSTRUCT*)lParam)->message) { case WM_QUERYENDSESSION: { switch( ((CWPSTRUCT*)lParam)->lParam ) { case ENDSESSION_LOGOFF: { FILE pFile = NULL; ((CWPSTRUCT)lParam)->message = 0; AfxMessageBox(TEXT(“log off”)); return 0; } break; } } } return ::CallNextHookEx(g_hMessage, code, wParam, lParam); }
判断是否为文件夹或者文件
1 | int IsDirectoryOrFile(CString strFileName) |
MyP2P V1.0 点对点聊天工具
Windows 任务管理器如何确定应用程序没有响应
最近参加的一个项目要求实现远程任务管理功能,也就是”Remote Task Manager”(RTM)。我把它与Windows NT的任务管理器进行了比较,发现标准的任务管理器显示应用程序的状态(正在运行或者没有响应)。标准的任务管理器发送(通过SendMessageTimeout函数)一个消息到主应用窗口,如果函数调用失败或者超时–则应用程序的状态就是”没有响应”,否则状态为”正在运行”。 但我发现还有一个更好的解决方法。本文将通过实例程序进行示范。这个方法的思路是通过调用User32.dll中一个未公开的函数来实现的。这个函数存在于Windows 9x和Windows NT/2000系统中,但在两个系统中的名字是不同的。Windows 9x系统中的名字为:IsHungThread,在Windows NT/2000系统中的名字为IsHungAppWindow。下面是它们的原型:
1 | BOOL IsHungAppWindow ( |
不幸的是,微软在User32.lib中没有提供这两个函数的输出。也就是说,这两个函数是未公开函数,如果要在程序中使用它们,则必须通过GetProcAddress和GetModuleHandle函数动态加载:
1 | typedef BOOL (WINAPI *PROCISHUNGAPPWINDOW) (HWND); |
利用未公布API获取CPU使用率
利用ntdll.dll中没有公开的API函数: NtQuerySystemInformation
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG); PROCNTQSI NtQuerySystemInformation;
NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQuerySystemInformation"
);
if (!NtQuerySystemInformation)
{ return; }
// get number of processors in the system
status = NtQuerySystemInformation(SystemBasicInformation,
&SysBaseInfo;,sizeof(SysBaseInfo),NULL);
if (status != NO_ERROR)
{ return; } status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo;,sizeof(SysTimeInfo),0); if (status!=NO_ERROR) { return; } // get new CPU’’s idle time status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo;,sizeof(SysPerfInfo),NULL); if (status != NO_ERROR) { return; } // if it’’s a first call - skip it if (m_liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(m_liOldIdleTime); dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(m_liOldSystemTime);
// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime = dbIdleTime / dbSystemTime;
// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5;
m_fNewUsges = (UINT)dbIdleTime;
}
VC中的自定义消息
Windows 应用程序所要做的每项工作几乎都是基于消息处理的, Windows 系统消息分为常用 Windows 消息,控件通知消息和命令。然而,有时我们需要定义自己的消息来通知程序什么事情发生了,这就是用户自定义消息。 ClassWizard 并没有提供增加用户自定义消息的功能,所以要使用用户自定义消息,必须手工编写代码。然后 ClassWizard 才可以象处理其它消息一样处理你自定义的消息。具体做法如下详解:
第一步:定义消息。一个消息实际上是开发 Windows95 应用程序时, Microsoft 推荐用户自定义消息至少是 WM_USER+100 ,因为很多新控件也要使用 WM_USER 消息。
第二步:实现消息处理函数。该函数使用 WPRAM 和 LPARAM 参数并返回 LPESULT 。
LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam){// TODO: 处理用户自定义消息 AfxMessageBox(“ 处理用户自定义消息 “); return 0;}
第三步:在类头文件的 AFX_MSG 块中说明消息处理函数: class CMainFrame:public CMDIFrameWnd{
…
// 一般消息映射函数
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()}
第四步:在用户类的消息块中,使用 ON_MESSAGE 宏指令将消息映射到消息处理函数中。 BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
ON_WM_CREATE()
ON_WM_TIMER()
ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)
这样,一个用户自定义消息就可以使用了,如果用户需要一个整个系统唯一的消息,可以调用 SDK 函数 RegisterWindowMessage 并使用 ON_REGISTER_MESSAGE 宏指令取代 ON_MESSAGE 宏指令,其余步骤同上。
VC++ 为程序员提供了一套功能强大、方便快捷的编程工具,它可以帮你方便的生成窗口、菜单等用户界面,可惜就是做出来的东西都一样,没有一点个性。下面,就介绍一些方法,让我们可以按照自己的设计定制出更加符合自己程序风格的窗口。

