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