Q
获取Windows外壳主窗口的句柄
A
在编程过程中,我们常常需要获取Windows外壳主窗口的句柄(HWND),微软在MSDN中提供了一个这样的函数:
HWND hwndShell = FindWindow("Program",NULL);
用这个函数可以满足我们的要求,但本文再提供一个更好的方法,用User32.dll中的GetShellWindow,这个函数的原型很简单:HWND GetShellWindow; 只是这个函数是个未公开的API函数,所以要使用它必须动态加载User32.dll。方法如下:
typedef HWND (WINAPI *PROCGETSHELLWND)();
PROCGETSHELLWND GetShellWindow;
HMODULE hUser32 = GetModuleHandle("user32");
GetShellWindow = (PROCGETSHELLWND)
GetProcAddress(hUser32,"GetShellWindow");
Q
如何向剪贴板发送字符串
A
假设你已有了名为My的对话框的工程.有了一个按钮并有了其响应的函数:OnButton1()
void CMyDlg::OnButton1()
{
CString str = "Some text";
::OpenClipboard(this->m_hWnd);
::EmptyClipboard();
HGLOBAL h = GlobalAlloc(GHND | GMEM_SHARE, str.GetLength() + 1);
strcpy((LPSTR)GlobalLock(h), str);
GlobalUnlock(h);
::SetClipboardData(CF_TEXT, h);
::CloseClipboard();
}
Q
任务管理器如何确定应用程序"没有响应"
A
最近参加的一个项目要求实现远程任务管理功能,也就是"Remote Task Manager"(RTM)。我把它与Windows NT的任务管理器进行了比较,发现标准的任务管理器显示应用程序的状态(正在运行或者没有响应)。标准的任务管理器发送(通过SendMessageTimeout函数)一个消息到主应用窗口,如果函数调用失败或者超时--则应用程序的状态就是"没有响应",否则状态为"正在运行"。
但我发现还有一个更好的解决方法。本文将通过实例程序进行示范。这个方法的思路是通过调用User32.dll中一个未公开的函数来实现的。这个函数存在于Windows 9x和Windows NT/2000系统中,但在两个系统中的名字是不同的。Windows 9x系统中的名字为:IsHungThread,在Windows NT/2000系统中的名字为IsHungAppWindow。下面是它们的原型:
BOOL IsHungAppWindow (
HWND hWnd, // 主应用窗口句柄
);
和
BOOL IsHungThread (
DWORD dwThreadId, // 主应用窗口的线程ID
);
不幸的是,微软在User32.lib中没有提供这两个函数的输出。也就是说,这两个函数是未公开函数,如果要在程序中使用它们,则必须通过GetProcAddress和GetModuleHandle函数动态加载:
typedef BOOL (WINAPI *PROCISHUNGAPPWINDOW) (HWND);
typedef BOOL (WINAPI *PROCISHUNGTHREAD) (DWORD);
PROCISHUNGAPPWINDOW IsHungAppWindow;
PROCISHUNGTHREAD IsHungThread;
HMODULE hUser32 = GetModuleHandle("user32");
IsHungAppWindow = (PROCISHUNGAPPWINDOW)
GetProcAddress(hUser32,"IsHungAppWindow");
IsHungThread = (PROCISHUNGTHREAD)
GetProcAddress(hUser32,"IsHungThread");
Q
Installshield快捷方式设置
A
在Desktop和Program下建立shortcut后,设置相应的属性:
1、Target设置为:<TARGETDIR>\Manage.exe
2、Start设置为:<TARGETDIR>
3、Install Conditions中选中App Exe..即可
建立卸载的快捷方式参数设置如下:
在Resources中加入一个快捷方式,设置“Traget”的VALUE为<DISK1TARGET>\setup.exe
设置PARAMETERS的VALUE为-uninst.
任何安装程序的Target都是设置为setup.exe
Q
计算文件目录的大小
A
#include <iostream>
#import "scrrun.dll" raw_interfaces_only
int main()
{
CoInitialize(NULL);
{
try
{
Scripting::IFileSystem3Ptr fs;
fs.CreateInstance(__uuidof(Scripting::FileSystemObject));
Scripting::IFolderPtr folder;
fs->GetFolder(_bstr_t("c:\\temp"),&folder);
_variant_t vsize;folder->get_Size(&vsize);
std::cout<<"c:\\temp size:"<<(long)vsize<<" bytes"<<std::endl;
}
catch(_com_error &e)
{
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
std::cout<<"Get directory size via FileSystemObject, by masterz"<<std::endl;
std::cout<<"COM error occurred,source:"<<(LPCTSTR)bstrSource<<std::endl;
std::cout<<"Description:"<<(LPCTSTR)bstrDescription<<std::endl;
}
}
CoUninitialize();
return 0;
}
Q
SDK设置EDIT密码属性
A
SendMessage(GetDlgItem(hWnd,IDC_EDIT_S08),EM_SETPASSWORDCHAR,(WPARAM)(UINT)'*',0)
Q. 如何捕获“插入优盘”的消息:
它是一个在ClassWizard中无法添加的消息,叫:OnDeviceChange
可以手工添加:
A.
afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData );
BOOL CMydemoDlg::OnDeviceChange( UINT nEventType, DWORD dwData )
{
MessageBox("Catched DeviceChange Message");
}
然后添加消息影射。在CMydemoDlg.cpp文件的开头那一段里面:
BEGIN_MESSAGE_MAP(CMydemoDlg, CDialog)
//{{AFX_MSG_MAP(CISP1581_demoDlg)
……
//}}AFX_MSG_MAP
ON_WM_DEVICECHANGE() //加到这里!注意位置!
END_MESSAGE_MAP()
关闭显示器:
::SendMessage(GetSafeHwnd(), WM_SYSCOMMAND, SC_MONITORPOWER, 1);
打开显示器:
::SendMessage(GetSafeHwnd(), WM_SYSCOMMAND, SC_MONITORPOWER, -1);
关机、注销、重启消息
WM_QUERYENDSESSION
得到系统时间、语言等的设置
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, lpLCData, cchData);
计算windows的运行时间
ULONG Time_mm =GetTickCount();
ULONG Time_sec =(Time_mm/1000)%60;
int Time_min =(Time_mm/(1000*60))%60;
int Time_hour =(Time_mm/(1000*60*60))%24;
int Time_day =(Time_mm/(1000*60*60*24));
cout<<Time_day<<" day(s) "<<Time_hour<<" hour(s) "<<Time_min<<" minute(s) "<<Time_sec<<"second(s).\n";
dos重定向输出到文本文件
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0))
{
MessageBox("Error On CreatePipe()");
return;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL,"c:\\winnt\\system32\\cmd.exe /c dir"
,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
DWORD dw = GetLastError();
MessageBox("Error on CreateProcess()");
return;
}
CloseHandle(hWrite);
char buffer[4096] = {0};
DWORD bytesRead;
while (true)
{
if (ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL)
break;
m_strResult+= buffer;
UpdateData(false);
Sleep(200);
}
}
获取有关窗口正在处理的当前消息的信息
GetCurrentMessage
void Base64(unsigned char chasc[3],unsigned char chuue[4])
{
int i,k=2;
unsinged char t=NULL;
for(i=0;i<3;i++)
{
*(chuue+i)=*(chasc+i)>>k;
*(chuue+i)|=t;
t=*(chasc+i)<<(8-k);
t>>=2;
k+=2;
}
*(chuue+3)=*(chasc+2)&63;
for(i=0;i<4;i++)
if((*(chuue+i)>=0)&&(*(chuue+i)<=25)) *(chuue+i)+=65;
else if((*(chuue+i)>=26)&&(*(chuue+i)<=51)) *(chuue+i)+=71;
else if((*(chuue+i)>=52)&&(*(chuue+i)<=61)) *(chuue+i)-=4;
else if(*(chuue+i)==62) *(chuue+i)=43;
else if(*(chuue+i)==63) *(chuue+i)=47;
}
void unBase64(unsigned char chuue[4],unsigned char chasc[3])
{int i,k=2;
unsigned char t=NULL;
for(i=0;i<4;i++)
if((*(chuue+i)>=65)&&(*(chuue+i)<=90)) *(chuue+i)-=65;
else if((*(chuue+i)>=97)&&(*(chuue+i)<=122)) *(chuue+i)-=71;
else if((*(chuue+i)>=48)&&(*(chuue+i)<=57)) *(chuue+i)+=4;
else if(*(chuue+i)==43) *(chuue+i)=62;
else if(*(chuue+i)==47) *(chuue+i)=63;
else if(*(chuue+i)==61) *(chuue+i)=0;
for(i=0;i<3;i++)
{*(chhex+i)=*(chuue+i)<<k;
k+=2;
t=*(chuue+i+1)>>8-k;
*(chhex+i)|=t;
}
}
枚举特定进程的所有线程列表【收集】
The following example obtains a list of running threads for the specified process. First, the RefreshThreadList function takes a
snapshot of the currently executing threads in the system using the CreateToolhelp32Snapshot function, then it walks through the list
recorded in the snapshot, using the Thread32First and Thread32Next functions. The parameter for RefreshThreadList is the identifier of
the process whose threads will be listed.
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
BOOL RefreshThreadList (DWORD dwOwnerPID)
{
HANDLE hThreadSnap = NULL;
BOOL bRet = FALSE;
THREADENTRY32 te32 = {0};
// Take a snapshot of all threads currently in the system.
hThreadSnap = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
return (FALSE);
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32);
// Walk the thread snapshot to find all threads of the process.
// If the thread belongs to the process, add its information
// to the display list.
if (Thread32First(hThreadSnap, &te32))
{
do
{
if (te32.th32OwnerProcessID == dwOwnerPID)
{
printf( "\nTID\t\t%d\n", te32.th32ThreadID);
printf( "Owner PID\t%d\n", te32.th32OwnerProcessID);
printf( "Delta Priority\t%d\n", te32.tpDeltaPri);
printf( "Base Priority\t%d\n", te32.tpBasePri);
}
}
while (Thread32Next(hThreadSnap, &te32));
bRet = TRUE;
}
else
bRet = FALSE; // could not walk the list of threads
// Do not forget to clean up the snapshot object.
CloseHandle (hThreadSnap);
return (bRet);
}
转自:http://blog.sina.com.cn/s/blog_5d8cc6410100e41x.html
Q
Q. 如何捕获“插入优盘”的消息:
A.
关闭显示器:
dos重定向输出到文本文件
枚举特定进程的所有线程列表【收集】
转自:http://blog.sina.com.cn/s/blog_5d8cc6410100e41x.html