控制台窗口隐藏与显示。hook实现控制台窗口最小化,窗口关闭消息截取

 
  
// #include "stdafx.h"
// #include "CardReaderHandler.h"
// 
// 
// int _tmain(int argc, _TCHAR* argv[])
// {	
// 	const char* confName = "./CardReaderConfig.ini";
// 	CardReaderMgr* m_pCRMgr = NULL;
// 	char	iPath[260] = {0};
// 	GetPrivateProfileStringA("PATH", "IDCARDREADER_DLLFILE", "", iPath, sizeof(iPath), confName);
// 	//启动读卡器
// #ifdef _DEBUG
// 	m_pCRMgr = new CardReaderMgr(iPath,confName);
// #else
// 	m_pCRMgr = new CardReaderMgr(iPath,confName);
// #endif
// 	if (m_pCRMgr  == NULL)
// 	{
// 		return 0;
// 	}
// 
// 	//获取版本号和动态库类型
// 	char* tmDllVersion = m_pCRMgr->GetDllVersion();
// 	int   tmTypeID = m_pCRMgr->GetDllType();
// 	if(tmDllVersion == NULL || -1 == tmTypeID)
// 	{
// 		printf("获取动态库失败");
// 		getchar();
// 		return false;
// 	}
// 
// 	switch(tmTypeID)
// 	{
// 	case 1:
// 		printf("---动态库名:博雅英杰\n");
// 		break;
// 	case 2:
// 		printf("---动态库名:国腾GTICR-100\n");
// 		break;
// 	case 3:
// 		printf("---动态库名:因纳伟盛\n");
// 		break;
// 	default:
// 		printf("---动态库名:未知\n");
// 		break;
// 	}
// 	
// 	CONN_SERVER_INFO stCardServerInfo;
// 	stCardServerInfo.m_nParentThreadID	=	0;
// 	stCardServerInfo.pMainCWnd			=   m_pCRMgr;
// 	stCardServerInfo.pCallBack			=   CardReaderMgr::CardReaderCallBack;
// 
// 	stCardServerInfo.m_nServerPort		=	12588;
// 	stCardServerInfo.m_nWM_USER			=	WM_IDCARDREADER;
// 
// 	m_pCRMgr->StartReadCard(stCardServerInfo);
// 
// 	getchar();
// 	return 0;
// }

//#if 0

#include "stdafx.h"
#include 
#include "CardReaderHandler.h"
#define IDR_PAUSE 12
#define IDR_START 13
/*
#include 
#pragma   comment(lib,   "shell32.lib") 
*/
HWND __hWnd;
LPCTSTR szAppName = TEXT("读卡器服务程序");
bool isDisplay = true;
HMENU hmenu;//菜单句柄

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	NOTIFYICONDATA nid;
	UINT WM_TASKBARCREATED;
	POINT pt;//用于接收鼠标坐标
	int xx;//用于接收菜单选项返回值

	// 不要修改TaskbarCreated,这是系统任务栏自定义的消息
	WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated"));
	switch (message)
	{
	case WM_CREATE://窗口创建时候的消息.SetConsoleTitle(L"TTT");
		/*AllocConsole();
		freopen("CONOUT$","w+t",stdout);
		freopen("CONIN$","r+t",stdin);
		SetConsoleTitle(L"TTT");
		__hWnd = ::FindWindow(NULL,L"TTT");
		ShowWindow(__hWnd,SW_HIDE);*/
		nid.cbSize = sizeof(nid);
		nid.hWnd = hwnd;
		nid.uID = 0;
		nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
		nid.uCallbackMessage = WM_USER;
		nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
		lstrcpy(nid.szTip, szAppName);
		Shell_NotifyIcon(NIM_ADD, &nid);
		hmenu=CreatePopupMenu();//生成菜单

		AppendMenu(hmenu,MF_STRING,IDR_PAUSE,_T("暂停服务"));//为菜单添加两个选项
		AppendMenu(hmenu,MF_STRING,IDR_START,_T("恢复服务"));
		break;
	case WM_USER://连续使用该程序时候的消息.
		if (lParam == WM_LBUTTONDOWN)
		{	
			if (isDisplay){
				ShowWindow(GetConsoleWindow(),SW_SHOW);				
				isDisplay = false;
			}else{
				ShowWindow(GetConsoleWindow(),SW_HIDE);
				isDisplay = true;
			}			
		}
		if (lParam == WM_LBUTTONDBLCLK)//双击托盘的消息,退出.
		{
			if(MessageBox(NULL,L"QUIT?",L"Console",MB_YESNO)==IDYES) SendMessage(hwnd,WM_CLOSE,NULL,NULL);
		}			
		if (lParam == WM_RBUTTONDOWN)
		{
			//GetCursorPos(&pt);//取鼠标坐标
			//::SetForegroundWindow(hwnd);//解决在菜单外单击左键菜单不消失的问题
			////EnableMenuItem(hmenu,IDR_PAUSE,MF_GRAYED);//让菜单中的某一项变灰
			//xx=TrackPopupMenu(hmenu,TPM_RETURNCMD,pt.x,pt.y,NULL,hwnd,NULL);//显示菜单并获取选项ID
			//if(xx==IDR_PAUSE)
			//{
			//	ShowWindow(__hWnd,SW_HIDE);
			//	//MessageBox(hwnd, TEXT("111"), szAppName, MB_OK);
			//}
			//if(xx==IDR_START)
			//{
			//	ShowWindow(__hWnd,SW_SHOW);
			//	//MessageBox(hwnd, TEXT("222"), szAppName, MB_OK);
			//}
			//if(xx==0) PostMessage(hwnd,WM_LBUTTONDOWN,NULL,NULL);
			////MessageBox(hwnd, TEXT("右键"), szAppName, MB_OK);
		}
		break;
	case WM_DESTROY://窗口销毁时候的消息.
		Shell_NotifyIcon(NIM_DELETE, &nid);;
		PostQuitMessage(0);
		break;
	default:
		/*
		* 防止当Explorer.exe 崩溃以后,程序在系统系统托盘中的图标就消失
		* 原理:Explorer.exe 重新载入后会重建系统任务栏。当系统任务栏建立的时候会向系统内所有
		* 注册接收TaskbarCreated 消息的顶级窗口发送一条消息,我们只需要捕捉这个消息,并重建系
		* 统托盘的图标即可。
		*/
		if (message == WM_TASKBARCREATED)
			SendMessage(hwnd, WM_CREATE, wParam, lParam);
		break;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}


// typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();
// PROCGETCONSOLEWINDOW GetConsoleWindow;
HHOOK hHook;
DWORD HookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
	if(nCode>=0&&wParam==WM_LBUTTONDOWN)
	{
		//printf("%d ")
		
		DWORD pt[2];
		memcpy(&pt[0],(void*)lParam,8);
		//printf("%d : %d :%d : %d\n",nCode,wParam,pt[0],pt[1]);
		if(SendMessage(GetConsoleWindow(),WM_NCHITTEST,0,(LPARAM)pt[0]+0x10000*pt[1])==HTCLOSE)
		{
			PostThreadMessage(GetCurrentThreadId(),WM_USER+1,0,0);
			return 1;
		}
		
		if(SendMessage(GetConsoleWindow(),WM_NCHITTEST,nCode,(LPARAM)pt[0]+0x10000*pt[1])==HTMINBUTTON)
		{
			PostThreadMessage(GetCurrentThreadId(),WM_USER+1,0,0);
			return 1;
		}
		
	}

	return CallNextHookEx(hHook,nCode,wParam,lParam);
}



// int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
// 				   LPSTR szCmdLine, int iCmdShow)

int _tmain(int argc, _TCHAR* argv[])
{
	  
//	__hWnd = GetConsoleHwnd();
	HWND hwnd;	
	MSG msg; 
	WNDCLASS wndclass;

	HWND handle = FindWindow(NULL, szAppName);
	if (handle != NULL)
	{
		MessageBox(NULL, TEXT("Application is already running"), szAppName, MB_ICONERROR);
		return 0;
	}	

// 	DeleteMenu(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE, MF_BYCOMMAND);
// 	DrawMenuBar(GetConsoleWindow());

	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = WndProc;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance =  GetModuleHandle(NULL);// hInstance;
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = szAppName;

	if (!RegisterClass(&wndclass))
	{
		MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
		return 0;
	}

	// 此处使用WS_EX_TOOLWINDOW 属性来隐藏显示在任务栏上的窗口程序按钮
	hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,
		szAppName, szAppName,
		WS_POPUP,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL, NULL, GetModuleHandle(NULL), NULL);

	ShowWindow(hwnd, 0);	
	UpdateWindow(hwnd);

	hHook=SetWindowsHookEx(14,(HOOKPROC)HookProc,NULL,NULL);
	while (GetMessage(&msg, NULL, 0, 0))
	{

		if(msg.message==WM_USER+1){
			ShowWindow(GetConsoleWindow(),SW_HIDE);
			isDisplay = true;
		}			
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	 UnhookWindowsHookEx(hHook);
	return msg.wParam;
}

//#endif

主要是做;当win32 控制台托盘图标实现,用钩子函数,hook实现控制台窗口关闭,窗口最小化的消息拦截,两个都是在网上找的,我主要做了下综合。哈哈。。。。

单击关闭按钮,窗口会隐藏,单击托盘图标,窗口会显示。

最小化也是同样的操作。



有bug。。


我还有篇文章是专门解决这个。


你可能感兴趣的:(Windows)