//this program use EnumChildWindows to enumerate all the child windows of the dialog... can be changed to enumerate all the child windows of the desktop. #include <afxtempl.h> // Information about child controls in the Visual Basic // ActiveX control. typedef struct xcontrol_info { HWND hwnd; // handle of child control char mnemonic_char; // mnemonic character key for the control } XCONTROL_INFO; class CTestVBDlg : public CDialog { ... // Array of info for child controls. CArray<XCONTROL_INFO, XCONTROL_INFO> m_XControlInfo; ... } // Callback function for EnumChildWindows() API BOOL CALLBACK EnumActiveXControlChildProc(HWND hwnd, LPARAM lParam) { CArray<XCONTROL_INFO, XCONTROL_INFO>* arr = (CArray<XCONTROL_INFO, XCONTROL_INFO>*)lParam; CString str; CWnd* control = CWnd::FromHandle(hwnd); control->GetWindowText(str); int index = str.Find('&'); // look for mnemonic // character keycode if (index > -1) { XCONTROL_INFO info; info.hwnd = hwnd; info.mnemonic_char = str[index+1]; arr->Add(info); } return TRUE; } BOOL CTestVBDlg ::OnInitDialog() { CDialog::OnInitDialog(); ... // Setup a callback function for EnumChildWindows() API to // enumerate all child windows of the ActiveX control. HWND hcontrol = GetDlgItem(IDC_VB_CONTROL1)->GetSafeHwnd(); EnumChildWindows(hcontrol, EnumActiveXControlChildProc, (LPARAM) &m_XControlInfo); return TRUE; } void CTestVBDlg ::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { // If user pressed an accelerator keystroke, loop through the // array to find out if it is one of the access keys for a // child control in the Visual Basic ActiveX control. BOOL trap_accel = nID == SC_KEYMENU; if (trap_accel) { int size = m_XControlInfo.GetSize(); for (int i = 0; i < size; i++) { if (toupper(LOWORD(lParam)) == toupper(m_XControlInfo[i].mnemonic_char)) { HWND child = m_XControlInfo[i].hwnd; ::SetFocus(child); ::SendMessage(child, BM_CLICK, 0, 0L); // OPTIONAL!!! } } } if (!trap_accel) CDialog::OnSysCommand(nID, lParam); } }
在程序中用 FINDWINDOW 找到窗口的 HANDLE,根据这个窗口的 HANDLE 可以找到相应的按钮的 HANDLE 。详细请查看MSDN中的FINDWINDOW。
[email protected]
在win2000任务管理器的“应用程序”里没有他的项目,
是不是就不能用FindWindow了?
你说的那个,jiangsheng刚刚告诉我了,
可是,那不是我想要的。:)我是想自己启动另一个只有一个对话框窗口的程序,
然后自动实现与点击某个按钮等同的功能。
{
hwnds = Search_Handle((LPCSTR)butt);
//AfxMessageBox(butt);
::SendMessage(hwnds,WM_KEYDOWN,VK_RETURN,0);
::SendMessage(hwnds,WM_KEYUP,VK_RETURN,0);
}
我要向另一程序的按钮发消息,以便实现等同于按下那个按钮的功能,
否则我都不能再说话了,我还没说完呢:)
继续……上面的那句代码错了,问题在下面:
HWND CCalculagraphDlg::Search_Handle(HWND h_parent,LPCSTR win_name)
{
HWND hwndWin = NULL; HWND hwndWin = hwndWin = ::GetWindow( h_parent, GW_CHILD ); int nLength = 0;
char szTitle[100] = { 0 };
while ( NULL != hwndWin )
{
nLength = ::GetWindowText( hwndWin, szTitle, 100 );
//此处根据szTitle是否是要找的
if(!strncmp(szTitle,win_name,20))
{
//find button.....
//AfxMessageBox(szTitle);
return hwndWin;
}
hwndWin = ::GetNextWindow( hwndWin, GW_HWNDNEXT );
}
return NULL;
}怎么不能返回找到的句柄?
原来不是函数,我改成函数就不好使了……
拜托各位帮帮忙阿。
ZeroMemory(szTitle,100);
1、使用EnumProcesses获得系统当前的进程ID数组
2、使用OpenProcess获得各个进程的句柄
3、使用GetModuleInformation获得进程的信息
4、取得其上层的Wnd,然后使用SendMessage,发WM_KEYDOWN和WM_KEYUP消息
这种方法通用性很好。
我试过你说得,没用,好像问题不在这。laiyinhate(爱死了C):
我怎么没得到?是这样,我用弹出maessagebox来测试的,
使用时我得程序启动那个软件,然后找到那个进程和那个按钮,
再向他发消息。
可是,我发现第一次执行这些
(我把这些整个的动作放进了一个按钮的响应方法里面了)
没有消息框出现,就是说成功找到,可是第二次再按那个按钮,
就出现了那个对话框。why? yfspace(异风):
你说的我要仔细看一下再说:)
我是用search_handle(...)找的,原来是一些语句,好使的,
因为我要用它找按钮的父窗口之后,还要用它来找那个按钮。
所以我才把那些做成函数的……刚刚仔细测试了一下,我找出错误了,
char mainwin[50] = {"EnterNet 300 [Adsl]"};
char butt[20] = {"Connect"};
HWND hwnds;
hwnds = Search_Handle(hwndWins,(LPCSTR)mainwin);
if(hwnds)
{
hwnds = NULL;//哈哈,我竟然是这样调用的……呵呵。好笨!:)
hwnds = Search_Handle(hwnds,(LPCSTR)butt);
if(!hwnds)
AfxMessageBox(butt);
::PostMessage(hwnds,BM_CLICK,0,0);
}
现在成功了,这个问题解决了。但是我还有个小问题,
当时我说找不到,
是因为我看到watch窗口中竟然有这个:
hwnds oxccccccccc
unused CXX0030:Error:Expression call这是什么意思阿?
我取得的桌面句柄就不这样,其他变量都不这样阿。
怎么回事?那是什么意思啊?
Sleep(1000);呵呵……
// ActiveX control.
typedef struct xcontrol_info
{
HWND hwnd; // handle of child control
char mnemonic_char; // mnemonic character key for the control
}
XCONTROL_INFO; class CTestVBDlg : public CDialog
{
...
// Array of info for child controls.
CArray<XCONTROL_INFO, XCONTROL_INFO> m_XControlInfo;
...
} // Callback function for EnumChildWindows() API
BOOL CALLBACK EnumActiveXControlChildProc(HWND hwnd, LPARAM lParam)
{
CArray<XCONTROL_INFO, XCONTROL_INFO>* arr =
(CArray<XCONTROL_INFO, XCONTROL_INFO>*)lParam; CString str;
CWnd* control = CWnd::FromHandle(hwnd);
control->GetWindowText(str);
int index = str.Find('&'); // look for mnemonic
// character keycode
if (index > -1)
{
XCONTROL_INFO info;
info.hwnd = hwnd;
info.mnemonic_char = str[index+1];
arr->Add(info);
} return TRUE;
} BOOL CTestVBDlg ::OnInitDialog()
{
CDialog::OnInitDialog();
... // Setup a callback function for EnumChildWindows() API to
// enumerate all child windows of the ActiveX control.
HWND hcontrol = GetDlgItem(IDC_VB_CONTROL1)->GetSafeHwnd();
EnumChildWindows(hcontrol, EnumActiveXControlChildProc,
(LPARAM) &m_XControlInfo);
return TRUE;
}
void CTestVBDlg ::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
// If user pressed an accelerator keystroke, loop through the
// array to find out if it is one of the access keys for a
// child control in the Visual Basic ActiveX control.
BOOL trap_accel = nID == SC_KEYMENU;
if (trap_accel)
{
int size = m_XControlInfo.GetSize();
for (int i = 0; i < size; i++)
{
if (toupper(LOWORD(lParam)) ==
toupper(m_XControlInfo[i].mnemonic_char))
{
HWND child = m_XControlInfo[i].hwnd;
::SetFocus(child); ::SendMessage(child, BM_CLICK, 0, 0L); // OPTIONAL!!!
}
}
} if (!trap_accel)
CDialog::OnSysCommand(nID, lParam);
}
}