C++;-如何退出没有窗口的程序? 我是C++新手,我自己做了一个小程序,可以通过在键盘上键入命令来启动程序。为了能够随时启动程序,我决定设置一个低级键盘挂钩,它可以跟踪按键的笔划,并在检测到特定命令时启动特定程序。简单的windows程序用于安装钩子,windows没有显示,因为我只需要钩子在后台监听
到目前为止,它工作正常,但是,一个小问题,但恼人的是我必须通过Windows任务管理器终止程序,这是相当不方便的。我通过按F7键成功地卸载了钩子,但似乎没有显示的windows程序是钩子的父程序,因此钩子无法退出windows程序。而我希望他们都通过按键终止。希望我已经说清楚了 有没有办法让我从钩子向windows程序发送一条消息,要求它退出?或者我可以在hook程序中终止它们 提前谢谢 以下是窗口程序的代码:C++;-如何退出没有窗口的程序? 我是C++新手,我自己做了一个小程序,可以通过在键盘上键入命令来启动程序。为了能够随时启动程序,我决定设置一个低级键盘挂钩,它可以跟踪按键的笔划,并在检测到特定命令时启动特定程序。简单的windows程序用于安装钩子,windows没有显示,因为我只需要钩子在后台监听,c++,windows,keyboard-hook,C++,Windows,Keyboard Hook,到目前为止,它工作正常,但是,一个小问题,但恼人的是我必须通过Windows任务管理器终止程序,这是相当不方便的。我通过按F7键成功地卸载了钩子,但似乎没有显示的windows程序是钩子的父程序,因此钩子无法退出windows程序。而我希望他们都通过按键终止。希望我已经说清楚了 有没有办法让我从钩子向windows程序发送一条消息,要求它退出?或者我可以在hook程序中终止它们 提前谢谢 以下是窗口程序的代码: #include <windows.h> #include "short
#include <windows.h>
#include "shortcut.h"
#pragma comment( lib, "libhook.dll.a") // Link Hook.lib to the project
long WINAPI WndProc(HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam)
{
switch(wMessage)
{
case WM_DESTROY:
InstallHook(FALSE); // Unhook
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, wMessage, wParam, lParam);
}
return 0;
}
BOOL FileExists(LPCTSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
WNDCLASS wndclass;
HANDLE hMutex = NULL;
char szAppName[20] = "shortcut";
hMutex = CreateMutex(NULL,TRUE,szAppName); //启动多线程
int dwRet = GetLastError();
if (hMutex)
{
if (dwRet == ERROR_ALREADY_EXISTS)
{
MessageBox(NULL, "Program is already runing.", "Oops!", MB_OK | MB_ICONINFORMATION);
CloseHandle(hMutex);
return FALSE;
}
}
wndclass.style=0;
wndclass.lpfnWndProc=(WNDPROC)WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=NULL;
wndclass.hCursor=LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName=(LPSTR)szAppName;
if(!RegisterClass(&wndclass))
return FALSE;
if (!FileExists("\\ShortCuts.txt"))
{
MessageBox(NULL, "Missing file: cannot load shortcut settings file.(Shortcuts.txt)", "ERROR",MB_OK|MB_ICONINFORMATION);
exit(1);
}
if (!InstallHook(TRUE))
exit(1);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
#包括
#包括“shortcut.h”
#pragma注释(lib,“libhook.dll.a”)//将Hook.lib链接到项目
长WINAPI WndProc(HWND-HWND、UINT-wMessage、WPARAM-WPARAM、LPARAM-LPARAM)
{
开关(wMessage)
{
案例WM_销毁:
InstallHook(FALSE);//取消挂钩
PostQuitMessage(0);
打破
违约:
返回DefWindowProc(hWnd、wMessage、wParam、lParam);
}
返回0;
}
BOOL文件存在(LPCTSTR szPath)
{
DWORD dwAttrib=GetFileAttributes(szPath);
返回(dwAttrib!=无效的文件属性&&
!(dwAttrib&FILE_属性_目录));
}
int WINAPI WinMain(HINSTANCE HINSTANCE,
HINSTANCE HPPreInstance、LPSTR lpszCmdLine、int nCmdShow)
{
味精;
WNDCLASS WNDCLASS;
句柄hMutex=NULL;
char szAppName[20]=“快捷方式”;
hMutex=CreateMutex(NULL,TRUE,szAppName)//启动多线程
int dwRet=GetLastError();
if(hMutex)
{
如果(dwRet==错误\u已存在)
{
MessageBox(NULL,“程序已在运行。”,“Oops!”,MB|U OK | MB|U图标信息);
密柄(hMutex);
返回FALSE;
}
}
wndclass.style=0;
lpfnWndProc=(WNDPROC)WNDPROC;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=NULL;
wndclass.hCursor=LoadCursor(空,IDC_箭头);
wndclass.hbrBackground=(HBRUSH)GetStockObject(灰色画笔);
wndclass.lpszMenuame=NULL;
wndclass.lpszClassName=(LPSTR)szAppName;
if(!RegisterClass(&wndclass))
返回FALSE;
如果(!FileExists(“\\ShortCuts.txt”))
{
MessageBox(NULL,“缺少文件:无法加载快捷方式设置文件。(Shortcuts.txt)”,“错误”,MB_OK | MB_图标信息);
出口(1);
}
如果(!InstallHook(TRUE))
出口(1);
while(GetMessage(&msg,NULL,0,0))
{
翻译信息(&msg);
发送消息(&msg);
}
返回msg.wParam;
}
以下是钩子程序的代码:
// Hook- a project to create the DLL and LIB files.
// Microsoft Visual C++ 6.0 and above steps:
// 1. Create a new Win32 Dynamic Link - Library project.
// 2. Add hook.cpp and hook.h to the project.
// 3. There is no step 3 :-). Just build your project and you will find
// a Hook.dll and Hook.lib file in your map.
#include <windows.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <ctime>
#include <map>
#include <process.h>
using namespace std;
HHOOK hHook;
HINSTANCE ghDLLInst=0;
const char startChar = ';';
bool bChecking = false;
string cmd;
typedef map<string,string> COMMANDMAP;
COMMANDMAP mShortcut;
string logfilename="log.txt";
ofstream LOG;
__declspec(dllexport)int InstallHook(BOOL bCode);
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwFunction, LPVOID lpNot)
{
ghDLLInst=(HINSTANCE)hModule;
return TRUE;
}
DWORD WINAPI Runsystem(LPVOID lpParam)
{
WinExec((LPCSTR)lpParam, SW_SHOW);
}
string gettime()
{
time_t curTime;
struct tm *locTime;
char buf[80];
time(&curTime);
locTime=localtime(&curTime);
strftime(buf,80,"%Y-%m-%d %H:%M:%S",locTime);
string s=buf;
return s;
}
ostream& tout()
{
return LOG<< gettime()<< ": ";
}
void StartCheck()
{
bChecking=true;
cmd.clear();
}
void EndCheck()
{
bChecking=false;
cmd.clear();
}
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if ((wParam == WM_KEYDOWN) && (nCode >= HC_ACTION)) // Only record when key pressed
{
KBDLLHOOKSTRUCT *pStruct = (KBDLLHOOKSTRUCT*)lParam;
switch (pStruct->vkCode)
{
case VK_RETURN:
{
if (bChecking)
{
COMMANDMAP::iterator it;
it=mShortcut.find(cmd);
if (it!=mShortcut.end())
{
tout()<<"received command \'"<<cmd<<"\', executing \'"<<it->second.c_str()<<endl;
CreateThread(NULL, 0, Runsystem, (void*)it->second.c_str(),0,NULL);
}
else {
tout()<<"received command \'" <<cmd<<"\', no matching."<<endl;
}
}
EndCheck();
break;
}
case VK_F7:
{
InstallHook(false);
break;
}
default: // Normal keys, convert them
{
BYTE KeyboardState[256];
GetKeyboardState(KeyboardState);
WORD CharValue;
if(ToAscii(pStruct->vkCode, pStruct->scanCode,KeyboardState,&CharValue,0) > 0) // Convert to char.
{
char character=char(CharValue);
// tout()<<"received keyCode: "<<pStruct->vkCode<< " char: "<< character<<endl;
if (bChecking)
{
cmd+=character;
}
if (!bChecking && (character == startChar))
{
// tout()<<"Start checking..."<<endl;
StartCheck();
}
}
break;
}
}
}
return (int)CallNextHookEx(hHook, nCode, wParam, lParam);
}
bool readline(ifstream &fin,string &sline)
{
do
{
getline(fin,sline);
} while (!fin.eof() && ((sline[0]=='/' && sline[1]=='/') || sline.empty()));
return fin.eof()?false:true;
}
// __declspec(dllexport) means that this function must be exported to a dll file.
__declspec(dllexport)int InstallHook(BOOL bCode)
{
if(bCode)
{
// initialize shortcuts
ifstream fin;
LOG.open(logfilename.c_str(),ios_base::app);
tout()<<"Reading config file."<<endl;
fin.open("ShortCuts.txt");
if (fin)
{
string scmd,spath;
char oneline[256];
while(readline(fin,scmd)&&readline(fin,spath))
{
mShortcut[scmd]=spath;
// LOG<<scmd<<','<<spath<<endl;
}
fin.close();
tout()<<"OK, "<<mShortcut.size()<<" shortcuts loaded."<<endl;
}
else
{
tout()<<"ERROR"<<endl;
LOG.close();
exit(0);
}
hHook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyboardProc, // Start the keyboard hook.
(HINSTANCE)GetModuleHandle(NULL), NULL);
if(!hHook)
{
tout()<<"Install hook failed."<<endl;
return 0;
}
else
{
tout()<<"Install hook successful."<<endl;
return 1;
}
}
else
{
if (MessageBox(NULL,"Are you sure to exit KeyShortcut?","Exit",MB_YESNO|MB_ICONWARNING)==IDYES)
{
tout()<<"Uninstall hook successful."<<endl;
LOG.close();
return UnhookWindowsHookEx(hHook); // Unhook the keyboardhook.
}
}
}
//Hook-用于创建DLL和LIB文件的项目。
//微软Visual C++ 6及以上步骤:
// 1. 创建新的Win32动态链接库项目。
// 2. 将hook.cpp和hook.h添加到项目中。
// 3. 没有步骤3:-)。只要建立你的项目,你就会发现
//地图中的Hook.dll和Hook.lib文件。
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
哈哈哈哈;
HINSTANCE ghDLLInst=0;
常量char startChar=';';
bool b检查=错误;
字符串cmd;
typedef-map命令图;
命令映射mShortcut;
字符串logfilename=“log.txt”;
流测井曲线;
__declspec(dllexport)intinstallhook(boolbcode);
布尔APIENTRY DllMain(句柄hModule、DWORD dwFunction、LPVOID lpNot)
{
ghDLLInst=(HINSTANCE)hModule;
返回TRUE;
}
DWORD WINAPI运行系统(LPVOID lpParam)
{
WinExec((LPCSTR)lpParam,西南展览);
}
字符串gettime()
{
时间短了;
struct tm*locTime;
char-buf[80];
时间(&curTime);
locTime=本地时间(&curTime);
strftime(buf,80,“%Y-%m-%d%H:%m:%S”,locTime);
字符串s=buf;
返回s;
}
ostream&tout()
{
返回LOGvkCode)
{
案例VK_返回:
{
如果(b检查)
{
COMMANDMAP::迭代器;
it=mShortcut.find(cmd);
if(it!=mShortcut.end())
{
tout()例如,您可以使用API函数为系统设置自己的热键,然后在程序中处理此热键的消息(无窗口)
添加:
如果您想将退出消息从一个进程发送到另一个进程,那么您的朋友是PostQuitMessage()还不够?谢谢您,Johnny,RegisterHotKey函数非常有用,它完美地解决了我的问题。再次感谢(: