I am developing a console program and I have planned to add a tray icon for it. But it seems that only Win32 GUI program can do something caused by messages. (WndProc()
)
My message checking loop code snippet: (Independent sub thread)
void WCH_message_loop() {
// Message loop.
MSG msg;
GetMessageW(&msg, nullptr, 0, 0);
Myn = new MyNotify(msg.hwnd);
MyC = new CTrayIcon();
MyC -> CreateTray(msg.hwnd, LoadIconW(NULL, IDI_ERROR), WCH_IDM_OPENPIC, L"Web Class Helper");
constexpr int ShowHide = 121;
constexpr int PrintScreen = 122;
RegisterHotKey(NULL, ShowHide, MOD_CONTROL, 'P');
RegisterHotKey(NULL, PrintScreen, MOD_CONTROL, VK_DOWN); // Register "Ctrl Down" hotkey.
while (GetMessage(&msg, nullptr, 0, 0)) {
if (msg.message == WM_HOTKEY) {
switch (msg.wParam) {
case ShowHide:
WCH_SetWindowStatus(!WCH_cmd_line);
break;
case PrintScreen:
cout << endl;
WCH_command_list.clear();
WCH_command_list = WCH_split("pi");
WCH_pi();
MyC -> ChangeTray(L"Successfully printed screen");
break;
default:
break;
}
}
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
WndProc()
function: (How could I bind it to something or make it take effect?)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
#ifdef _DEBUG
WCH_printlog(WCH_LOG_STATUS_DEBUG, "Starting \"WndProc()\"");
#endif
switch (message) {
case 1025:
switch (lParam) {
case WM_LBUTTONDOWN:
WCH_SetWindowStatus(true);
break;
case WM_RBUTTONDOWN:
WCH_SetTrayIconMenu(hWnd);
break;
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case WCH_IDM_SHOWHIDE:
WCH_SetWindowStatus(!WCH_cmd_line);
break;
case WCH_IDM_EXIT:
exit(0);
break;
default:
return DefWindowProcW(hWnd, message, wParam, lParam);
break;
}
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd, message, wParam, lParam);
}
return 0;
}
Dependent code snippet:
class CTrayIcon {
public:
CTrayIcon() {};
~CTrayIcon() {};
BOOL CreateTray(HWND, HICON, UINT, LPCTSTR = L"Web Class Helper");
BOOL ChangeTray(LPCTSTR, LPCTSTR = L"Web Class Helper", UINT = 3000);
BOOL DeleteTray();
private:
NOTIFYICONDATA m_Notify;
};
struct MyNotify {
MyNotify(HWND hWND, WCHAR* Path = (WCHAR*)L"WCHs.ico", WCHAR* Title = (WCHAR*)L"Web Class Helper", UINT uID = 1) {
NOTIFYICONDATA nID = {};
nID.hIcon = (HICON)LoadImageW(NULL, Path, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
wcscpy_s(nID.szTip, Title);
nID.hWnd = hWND;
nID.uID = uID;
nID.uFlags = NIF_GUID | NIF_ICON | NIF_MESSAGE | NIF_TIP;
nID.uCallbackMessage = 1025;
Shell_NotifyIconW(NIM_ADD, &nID);
}
};
ATOM WCH_RegisterClass(HINSTANCE hInstance, WCHAR* szWindowClass) {
#ifdef _DEBUG
WCH_printlog(WCH_LOG_STATUS_DEBUG, "Registering class");
#endif
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_WCH));
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW 1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WCH);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIconW(wcex.hInstance, MAKEINTRESOURCEW(IDI_SMALL));
return RegisterClassExW(&wcex);
}
How could I solve this problem? Thanks!
Now I don't know why does WndProc()
do not work. (Maybe just in GUI program?)
But I don't want to convert it to GUI program.