我是靠谱客的博主 炙热外套,最近开发中收集的这篇文章主要介绍公司程序有被夺取焦点的情况,需要用户手动切出切入,暂写个demo(其实是挖坑)查找焦点丢失的问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

查找焦点丢失的问题

查百度说是有其他程序抢夺了焦点,有人写了小程序,我也搜一下,模仿模仿.
在模仿过程中,不幸用了个系统推荐但不熟悉函数(wcscpy_s():为了这个专门加了个miniDump,可不知道为什么还是定位不到),挖了个坑,在此主要就是为了记录这个坑.

定时器是个很不好的方法,不过指示测试的话也够了.
为什么别人家的代码看起来那么好用,我就只配用定时器,没天理啊!!!

原参考:如何找到WIN7中夺去焦点的程序? - 知乎 @liyb

// 代码备份
// 定时器检查获取前端窗口
// 2020-1-7 17:56:39
// GetFocusInfo.cpp
#include <iostream>
#include <Windows.h>
#include "DbgHelp.h"
#define DUMPMSGBOX
// windows下c++代码保存dump文件_jigetage的专栏-CSDN博客
// https://blog.csdn.net/jigetage/article/details/80757559
int GenerateMiniDump(PEXCEPTION_POINTERS pExceptionPointers)
{
MessageBox(NULL, L"Init", L"GenerateMiniDump", MB_OK);
// 定义函数指针
typedef BOOL(WINAPI * MiniDumpWriteDumpT)(
HANDLE,
DWORD,
HANDLE,
MINIDUMP_TYPE,
PMINIDUMP_EXCEPTION_INFORMATION,
PMINIDUMP_USER_STREAM_INFORMATION,
PMINIDUMP_CALLBACK_INFORMATION
);
// 从 "DbgHelp.dll" 库中获取 "MiniDumpWriteDump" 函数
MiniDumpWriteDumpT pfnMiniDumpWriteDump = NULL;
HMODULE hDbgHelp = LoadLibrary(TEXT("DbgHelp.dll"));
DUMPMSGBOX MessageBox(NULL, L"DbgHelp.dll", L"LoadLibrary", MB_OK);
if (NULL == hDbgHelp)
{
return EXCEPTION_CONTINUE_EXECUTION;
}
pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
if (NULL == pfnMiniDumpWriteDump)
{
FreeLibrary(hDbgHelp);
return EXCEPTION_CONTINUE_EXECUTION;
}
DUMPMSGBOX MessageBox(NULL, L"MiniDumpWriteDump", L"GetProcAddress", MB_OK);
// 创建 dmp 文件件
TCHAR szFileName[MAX_PATH] = { 0 };
TCHAR* szVersion = TEXT("DumpDemo_v1.0");
SYSTEMTIME stLocalTime;
GetLocalTime(&stLocalTime);
wsprintf(szFileName, L"%s-%04d%02d%02d-%02d%02d%02d.dmp",
szVersion, stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);
HANDLE hDumpFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
if (INVALID_HANDLE_VALUE == hDumpFile)
{
FreeLibrary(hDbgHelp);
return EXCEPTION_CONTINUE_EXECUTION;
}
DUMPMSGBOX MessageBox(NULL, L"szFileName", L"CreateFile", MB_OK);
// 写入 dmp 文件
MINIDUMP_EXCEPTION_INFORMATION expParam;
expParam.ThreadId = GetCurrentThreadId();
expParam.ExceptionPointers = pExceptionPointers;
expParam.ClientPointers = FALSE;
pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers ? &expParam : NULL), NULL, NULL);
// 释放文件
CloseHandle(hDumpFile);
FreeLibrary(hDbgHelp);
DUMPMSGBOX MessageBox(NULL, L"hDbgHelp", L"FreeLibrary", MB_OK);
return EXCEPTION_EXECUTE_HANDLER;
}
LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
{
DUMPMSGBOX MessageBox(NULL, L"Init", L"ExceptionFilter", MB_OK);
// 这里做一些异常的过滤或提示
if (IsDebuggerPresent())
{
return EXCEPTION_CONTINUE_SEARCH;
}
return GenerateMiniDump(lpExceptionInfo);
}
// SetUnhandledExceptionFilter无法捕获异常原因及解决方法_kevin3683的专栏-CSDN博客
// https://blog.csdn.net/kevin3683/article/details/19040809
void DisableSetUnhandledExceptionFilter()
{
// 无法得知此代码来源于
#ifndef _M_IX86
#error "The following code only works for x86!"
#endif
// 此函数一旦成功调用,之后对 SetUnhandledExceptionFilter 的调用将无效
void* addr = (void*)GetProcAddress(LoadLibrary(L"kernel32.dll"), "SetUnhandledExceptionFilter");
if (addr)
{
unsigned char code[16];
int size = 0;
code[size++] = 0x33;
code[size++] = 0xC0;
code[size++] = 0xC2;
code[size++] = 0x04;
code[size++] = 0x00;
DWORD dwOldFlag, dwTempFlag;
VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);
WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);
VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);
}
}
int main()
{
SetUnhandledExceptionFilter(ExceptionFilter);
DisableSetUnhandledExceptionFilter();
// 不加这个,会有些Crash捕获不到,比如wcscpy_s()
// 基于VS2010 开发的Release版本软件异常崩溃后快速定位bug相关方法_tormi21c的博客-CSDN博客
// https://blog.csdn.net/tormi21c/article/details/88376619
//
int *c = NULL;
//
*c = 123;
// wchar_t 的输出问题_风吹草地pp凉的博客-CSDN博客
// https://blog.csdn.net/blue1244/article/details/9245029
// 设置输出编码
std::wcout.imbue(std::locale("chs"));
std::wcout.imbue(std::locale(""));
setlocale(LC_ALL, "Chinese-simplified");
int iBufLen = 1024;
WCHAR*strWnd = new WCHAR[iBufLen];
memset(strWnd, 0, iBufLen);
WCHAR*strCtrl = new WCHAR[iBufLen];
memset(strCtrl, 0, iBufLen);
while (true)
{
// 获取活动窗口输入焦点控件句柄的方法_leevans的专栏-CSDN博客
// https://blog.csdn.net/leevans/article/details/7318023
// 获取活动窗口及获得控件句柄
HWND hForeWnd = ::GetForegroundWindow();
DWORD dwSelfThreadId = GetCurrentThreadId();
DWORD dwForeThreadId = GetWindowThreadProcessId(hForeWnd, NULL);
AttachThreadInput(dwForeThreadId, dwSelfThreadId, true);
HWND hFocus = ::GetFocus();
GetWindowTextW(hForeWnd, strWnd, iBufLen-1);
if (hFocus != NULL)
{
GetWindowTextW(hFocus, strCtrl, iBufLen-1);
}
else
{
WCHAR wc[128] = L"[NULL]";
wcscpy(strCtrl, wc);
//wcscpy_s(strCtrl, wcslen(wc), wc);
// Release异常退出,Debug未抓取到,miniDump定位不到
}
DWORD pid = 0;
DWORD dRtn = GetWindowThreadProcessId(hForeWnd, &pid);
AttachThreadInput(dwForeThreadId, dwSelfThreadId, false);
// 输出内容
printf("n==========%lldn", GetTickCount64());
printf("当前进程ID
:%un", GetCurrentProcessId());
printf("当前线程ID
:%un", dwSelfThreadId);
printf("活动进程ID
:%un", pid);
printf("活动线程ID
:%un", dwForeThreadId);
printf("活动窗口句柄
:%d(10) - %x(16)n", hForeWnd, hForeWnd);
printf("活动控件句柄
:%d(10) - %x(16)n", hFocus, hFocus);
printf("活动窗口标题[%d]:%wsn", wcslen(strWnd), strWnd);
printf("活动控件标题[%d]:%wsn", wcslen(strCtrl), strCtrl);
Sleep(3000);
}
delete[] strWnd;
delete[] strCtrl;
return 0;
}

最后

以上就是炙热外套为你收集整理的公司程序有被夺取焦点的情况,需要用户手动切出切入,暂写个demo(其实是挖坑)查找焦点丢失的问题的全部内容,希望文章能够帮你解决公司程序有被夺取焦点的情况,需要用户手动切出切入,暂写个demo(其实是挖坑)查找焦点丢失的问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部