![](/img/trans.png)
[英]How can I make my program exit the for loop when it reaches 10000? C++
[英]C++ - How can I exit a program that has no window?
我是C ++的新手,我為自己制作了一個小程序,可以通過在鍵盤上鍵入命令來啟動程序。 為了能夠在需要時啟動程序,我決定設置一個低級鍵盤掛鈎,該鍵盤掛鈎可以跟蹤按鍵並在檢測到特定命令時啟動特定程序。 簡單的Windows程序用於安裝該鈎子,未顯示Windows,因為我只需要在后台監聽鈎子即可。
到目前為止,它仍然可以正常工作,但是,一個較小但煩人的問題是我必須通過Windows Task Manager終止程序,這非常不方便。 我已經設法通過按F7鍵卸載了該掛鈎,但是似乎未顯示的Windows程序是該掛鈎的父項,因此該掛鈎無法退出Windows程序。 當我希望它們都通過按鍵終止時。 希望我已經說清楚了。
有什么方法可以將消息從掛鈎發送到Windows程序以要求其退出? 或者以某種方式可以在鈎子程序中終止它們兩者?
提前致謝。
這是窗口程序的代碼:
#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;
}
這是鈎子程序的代碼:
// 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.
}
}
}
例如,您可以使用RegisterHotKey API函數將自己的熱鍵設置為系統,然后在程序中處理此熱鍵的消息(無窗口)
補充:如果您想從一個進程向另一個進程發送退出消息,那么您的朋友就是PostThreadMessage(dwThreadId,WM_DESTROY,0,0);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.