unreal engine 给游戏创建托盘图标,右键菜单

plugin

https://github.com/ue4plugins/WindowsMessageHandlerExample

关闭editor,解压后新建一个Plugins文件夹,放到 /Plugins 文件夹
unreal engine 给游戏创建托盘图标,右键菜单_第1张图片

然后打开***.sln,build

右键uproject,generate project fils

unreal engine 给游戏创建托盘图标,右键菜单_第2张图片

再打开editor,Enable plugin ,可以在Output看到已经在运行了;

unreal engine 给游戏创建托盘图标,右键菜单_第3张图片
unreal engine 给游戏创建托盘图标,右键菜单_第4张图片

重新打开vs,可以看到plugin的代码,WindowsMessageHandlerExampleModule.cpp

unreal engine 给游戏创建托盘图标,右键菜单_第5张图片

修改plugin代码

创建一个托盘

class FExampleHandler

icon在package之后的主目录

#if PLATFORM_WINDOWS
#include "Windows/MinWindows.h"
#include 
#include 
#endif
NOTIFYICONDATA m_nfData;
#define NOTIFY_SHOW WM_USER+2500
#define IDR_MAINFRAME WM_USER +2501




bool CreateIco()
	{
		HWND hWnd = GetActiveWindow();
		m_nfData.hWnd = hWnd;

		// 图标路径是package之后的目录,打包完把图标放到启动程序同一个文件夹
		const FString pathLaunch = FPaths::LaunchDir() + "icon.ico";
		UE_LOG(LogTemp, Warning, TEXT(">>> FPATHS : %s"), *pathLaunch);
		HINSTANCE hInst = NULL;
		HICON hIcon = (HICON)LoadImage(hInst, *(pathLaunch), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_LOADFROMFILE);

		const uint32 Error = GetLastError();
		GLog->Logf(TEXT("%d"), Error);


		m_nfData.cbSize = sizeof(NOTIFYICONDATA); 
		m_nfData.uID = IDR_MAINFRAME;
		m_nfData.hIcon = hIcon;
		m_nfData.hWnd = hWnd;
		m_nfData.uCallbackMessage = NOTIFY_SHOW;
		m_nfData.uVersion = NOTIFYICON_VERSION;
		m_nfData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;
		lstrcpy(m_nfData.szTip, L"托盘"); //szAppClassName

		UE_LOG(LogTemp, Warning, TEXT(">>> Shell_NotifyIcon : "));
	
		return Shell_NotifyIcon(NIM_ADD, &m_nfData);
	}


移除托盘

class FExampleHandler

bool DeleteIco()
	{
		return Shell_NotifyIcon(NIM_DELETE, &m_nfData);
	}

给托盘加菜单

	// 添加菜单
	void AddTrayMenu(HWND Hwnd)
	{

		POINT pt;

		GetCursorPos(&pt);
		HMENU menu = CreatePopupMenu();

		// quit
		AppendMenu(menu, MF_STRING, WM_DESTROY, L"quit");

		::SetForegroundWindow(Hwnd);
		int32 MenuID = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, NULL, Hwnd, NULL);

		GLog->Logf(TEXT("%d"), MenuID);

		if (MenuID == WM_DESTROY)
		{
			UE_LOG(LogTemp, Warning, TEXT(">>> WM_DESTROY : "));
			// 退出
			RequestEngineExit("exit");
		}

		DestroyMenu(menu);
	}

处理Message

virtual bool ProcessMessage(HWND Hwnd, uint32 Message, WPARAM WParam, LPARAM LParam, int32& OutResult) override
	{
		// log out some details for the received message
		GLog->Logf(TEXT("WindowsMessageHandlerExampleModule: hwnd = %i, msg = %s, wParam = %i, lParam = %i"), Hwnd, *GetMessageName(Message), WParam, LParam);

		switch (Message)
		{
		case NOTIFY_SHOW:
			{
				switch (LParam)
				{
                    // 右键弹出菜单
				case WM_RBUTTONUP:
					AddTrayMenu(Hwnd);
					break;				

				}
			}


			return false;
		}
	};

package

打包完,把图标放到启动程序目录

unreal engine 给游戏创建托盘图标,右键菜单_第6张图片

在这里插入图片描述

在这里插入图片描述

修改后的plugin完整代码

WindowsMessageHandlerExampleModule.cpp


// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#include "Framework/Application/SlateApplication.h"
#include "Misc/OutputDevice.h"
#include "Modules/ModuleInterface.h"
#include "Modules/ModuleManager.h"
#include "Windows/WindowsApplication.h"

#include "WindowsMessageHelpers.h"

#define LOCTEXT_NAMESPACE "FWindowsMessageHandlerExampleModule"
#if PLATFORM_WINDOWS
#include 
#include 
#include "Windows/MinWindows.h"
#endif


NOTIFYICONDATA nid;

#define NOTIFY_SHOW WM_USER+2500
#define IDR_MAINFRAME WM_USER +2501

/**
 * Example Windows message handler.
 */
class FExampleHandler
	: public IWindowsMessageHandler
{
public:
	bool CreateIco()
	{
		HWND hWnd = GetActiveWindow();
		nid.hWnd = hWnd;

		// 图标路径是package之后,主目录
		const FString pathLaunch = FPaths::LaunchDir() + "icon.ico";
		UE_LOG(LogTemp, Warning, TEXT(">>> FPATHS : %s"), *pathLaunch);
		HINSTANCE hInst = NULL;
		HICON hIcon = (HICON)LoadImage(hInst, *(pathLaunch), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_LOADFROMFILE);

		const uint32 Error = GetLastError();
		GLog->Logf(TEXT("%d"), Error);


		nid.cbSize = sizeof(NOTIFYICONDATA); 
		nid.uID = IDR_MAINFRAME;
		nid.hIcon = hIcon;
		nid.hWnd = hWnd;
		nid.uCallbackMessage = NOTIFY_SHOW;
		nid.uVersion = NOTIFYICON_VERSION;
		nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;
		lstrcpy(nid.szTip, L"LOOP TIMER"); //szAppClassName

		UE_LOG(LogTemp, Warning, TEXT(">>> Shell_NotifyIcon : "));
	
		return Shell_NotifyIcon(NIM_ADD, &nid);
	}
	
	bool DeleteIco()
	{
		return Shell_NotifyIcon(NIM_DELETE, &nid);
	}
	
	// 添加菜单
	void AddTrayMenu(HWND Hwnd)
	{

		POINT pt;

		GetCursorPos(&pt);
		HMENU menu = CreatePopupMenu();

		// quit
		AppendMenu(menu, MF_STRING, WM_DESTROY, L"quit");

		::SetForegroundWindow(Hwnd);
		int32 MenuID = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, NULL, Hwnd, NULL);

		GLog->Logf(TEXT("%d"), MenuID);

		if (MenuID == WM_DESTROY)
		{
			UE_LOG(LogTemp, Warning, TEXT(">>> WM_DESTROY : "));
			// 退出
			RequestEngineExit("exit");
		}

		DestroyMenu(menu);
	}


	//~ IWindowsMessageHandler interface

	virtual bool ProcessMessage(HWND Hwnd, uint32 Message, WPARAM WParam, LPARAM LParam, int32& OutResult) override
	{
		// log out some details for the received message
		GLog->Logf(TEXT("WindowsMessageHandlerExampleModule: hwnd = %i, msg = %s, wParam = %i, lParam = %i"), Hwnd, *GetMessageName(Message), WParam, LParam);

		switch (Message)
		{
		case NOTIFY_SHOW:
			{
				switch (LParam)
				{
				case WM_RBUTTONUP:
					AddTrayMenu(Hwnd);
					break;
								
				}
			}

			//...
		}
		
		// we did not handle this message, so make sure it gets passed on to other handlers
		return false;
	}
};


/**
 * Implements the WindowsMessageHandlerExample module.
 */
class FWindowsMessageHandlerExampleModule
	: public IModuleInterface
{
public:

	//~ IModuleInterface interface

	virtual void StartupModule() override
	{
		
		// register our handler
		FWindowsApplication* Application = GetApplication();
        // -----------------------托盘-------------------------
		Handler.CreateIco();
		if (Application != nullptr)
		{
			Application->AddMessageHandler(Handler);
		}
	}


	virtual void ShutdownModule() override
	{
		
		// unregister our handler
		FWindowsApplication* Application = GetApplication();
        // -----------------------移除托盘-------------------------
		Handler.DeleteIco();
		if (Application != nullptr)
		{
			Application->RemoveMessageHandler(Handler);
		}
	}

protected:

	FWindowsApplication* GetApplication() const
	{
		if (!FSlateApplication::IsInitialized())
		{
			return nullptr;
		}

		return (FWindowsApplication*)FSlateApplication::Get().GetPlatformApplication().Get();
	}

private:

	FExampleHandler Handler;
};


#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FWindowsMessageHandlerExampleModule, WindowsMessageHandlerExample)



参考

https://blog.csdn.net/u014532636/article/details/80451370
https://unrealengine.com/id/authorize?client_id=c4c02c7c99e94ed9870a9dbeafab2c3f&response_type=code

你可能感兴趣的:(unreal,engine,unreal4,unreal)