mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
- Manage/About dialogs: Fixed that keyboard commands didn't work
- Window message API: Partly broken since r1157, fixed - Moved all functionality from Rainmeter.exe into Rainmeter.dll
This commit is contained in:
parent
4d814bbd58
commit
2c6ed8ed69
@ -17,10 +17,9 @@
|
||||
*/
|
||||
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <crtdbg.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <Windows.h>
|
||||
#include "../Library/Rainmeter.h"
|
||||
|
||||
#if defined _M_IX86
|
||||
@ -34,296 +33,12 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Protos
|
||||
*/
|
||||
BOOL InitApplication(HINSTANCE hInstance, const WCHAR* WinClass);
|
||||
HWND InitInstance(HINSTANCE hInstance, const WCHAR* WinClass, const WCHAR* WinName);
|
||||
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
void Bang(const WCHAR* command);
|
||||
HMODULE RmLoadSystemLibrary(LPCWSTR lpLibFileName);
|
||||
BOOL IsRunning(HANDLE* hMutex);
|
||||
|
||||
/*
|
||||
** Stuff from the DLL
|
||||
*/
|
||||
EXPORT_PLUGIN int Initialize(HWND hWnd, HINSTANCE hInstance, LPCWSTR lpCmdLine);
|
||||
EXPORT_PLUGIN void Quit();
|
||||
EXPORT_PLUGIN void ExecuteBang(LPCTSTR szBang);
|
||||
|
||||
const WCHAR* WinClass = L"DummyRainWClass";
|
||||
const WCHAR* WinName = L"Rainmeter control window";
|
||||
|
||||
enum RetValue
|
||||
{
|
||||
RetSuccess = 0,
|
||||
RetError = 1
|
||||
};
|
||||
|
||||
/*
|
||||
** WinMain
|
||||
** wWinMain
|
||||
**
|
||||
** The Main-function
|
||||
** Entry point.
|
||||
**
|
||||
*/
|
||||
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
HANDLE hMutex = NULL;
|
||||
MSG msg;
|
||||
BOOL bRet;
|
||||
|
||||
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||
// _CrtSetBreakAlloc(5055);
|
||||
|
||||
// Avoid loading a dll from current directory
|
||||
SetDllDirectory(L"");
|
||||
|
||||
if (lpCmdLine && lpCmdLine[0] == L'!')
|
||||
{
|
||||
// It's a !bang
|
||||
Bang(lpCmdLine);
|
||||
return RetSuccess;
|
||||
}
|
||||
|
||||
// Check whether Rainmeter.exe is already running
|
||||
if (IsRunning(&hMutex))
|
||||
{
|
||||
//MessageBox(NULL, L"Rainmeter.exe is already running.", L"Rainmeter", MB_ICONWARNING | MB_TOPMOST | MB_OK);
|
||||
return RetSuccess;
|
||||
}
|
||||
|
||||
if (!InitApplication(hInstance, WinClass)) return RetError;
|
||||
|
||||
HWND hWnd = InitInstance(hInstance, WinClass, WinName);
|
||||
if (!hWnd) return RetError;
|
||||
|
||||
// Check that the DLL is available and initialize it
|
||||
HMODULE module = GetModuleHandle(L"Rainmeter.dll");
|
||||
if (module == NULL || Initialize(hWnd, module, lpCmdLine) == 1)
|
||||
{
|
||||
DestroyWindow(hWnd);
|
||||
return RetError;
|
||||
}
|
||||
|
||||
// Run the standard window message loop
|
||||
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
|
||||
{
|
||||
if (bRet == -1) // error
|
||||
{
|
||||
Quit();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (hMutex) ReleaseMutex(hMutex);
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
|
||||
/*
|
||||
** InitApplication
|
||||
**
|
||||
** Creates the windowclass
|
||||
**
|
||||
*/
|
||||
BOOL InitApplication(HINSTANCE hInstance, const WCHAR* WinClass)
|
||||
{
|
||||
WNDCLASS wc = {0};
|
||||
wc.lpfnWndProc = (WNDPROC)MainWndProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.lpszClassName = WinClass;
|
||||
|
||||
return RegisterClass(&wc);
|
||||
}
|
||||
|
||||
/*
|
||||
** InitInstance
|
||||
**
|
||||
** Creates the window. This is just an invisible window. The real window
|
||||
** is created by the DLL.
|
||||
**
|
||||
*/
|
||||
HWND InitInstance(HINSTANCE hInstance, const WCHAR* WinClass, const WCHAR* WinName)
|
||||
{
|
||||
return CreateWindowEx(
|
||||
WS_EX_TOOLWINDOW,
|
||||
WinClass,
|
||||
WinName,
|
||||
WS_POPUP | WS_DISABLED,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
hInstance,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
** Bang
|
||||
**
|
||||
** Sends bangs to the DLL
|
||||
**
|
||||
*/
|
||||
void Bang(const WCHAR* command)
|
||||
{
|
||||
// Check if Rainmeter is running
|
||||
HWND wnd = FindWindow(WinClass, WinName);
|
||||
if (wnd != NULL)
|
||||
{
|
||||
COPYDATASTRUCT copyData;
|
||||
|
||||
copyData.dwData = 1;
|
||||
copyData.cbData = (DWORD)((wcslen(command) + 1) * sizeof(WCHAR));
|
||||
copyData.lpData = (void*)command;
|
||||
|
||||
// Send the bang to the Rainmeter window
|
||||
SendMessage(wnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)©Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_wcsicmp(L"!rainmeterquit", command) != 0 &&
|
||||
_wcsicmp(L"!quit", command) != 0)
|
||||
{
|
||||
MessageBox(NULL, L"Rainmeter is not running.\nUnable to send the !bang to it.", L"Rainmeter", MB_OK | MB_TOPMOST | MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RmLoadSystemLibrary
|
||||
**
|
||||
** Loads a system dll from system32 directory.
|
||||
**
|
||||
*/
|
||||
HMODULE RmLoadSystemLibrary(LPCWSTR lpLibFileName)
|
||||
{
|
||||
WCHAR buffer[MAX_PATH];
|
||||
std::wstring path;
|
||||
|
||||
if (GetSystemDirectory(buffer, MAX_PATH))
|
||||
{
|
||||
path = buffer;
|
||||
path += L'\\';
|
||||
path += lpLibFileName;
|
||||
|
||||
return LoadLibrary(path.c_str());
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** IsRunning
|
||||
**
|
||||
** Checks whether Rainmeter.exe is running.
|
||||
**
|
||||
*/
|
||||
BOOL IsRunning(HANDLE* hMutex)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
ULONG i[2];
|
||||
ULONG buf[4];
|
||||
unsigned char in[64];
|
||||
unsigned char digest[16];
|
||||
} MD5_CTX;
|
||||
|
||||
typedef void (WINAPI *FPMD5INIT)(MD5_CTX *context);
|
||||
typedef void (WINAPI *FPMD5UPDATE)(MD5_CTX *context, const unsigned char *input, unsigned int inlen);
|
||||
typedef void (WINAPI *FPMD5FINAL)(MD5_CTX *context);
|
||||
|
||||
// Create MD5 digest from command line
|
||||
HMODULE hCryptDll = RmLoadSystemLibrary(L"cryptdll.dll");
|
||||
if (!hCryptDll) // Unable to check the mutex
|
||||
{
|
||||
*hMutex = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FPMD5INIT MD5Init = (FPMD5INIT)GetProcAddress(hCryptDll, "MD5Init");
|
||||
FPMD5UPDATE MD5Update = (FPMD5UPDATE)GetProcAddress(hCryptDll, "MD5Update");
|
||||
FPMD5FINAL MD5Final = (FPMD5FINAL)GetProcAddress(hCryptDll, "MD5Final");
|
||||
if (!MD5Init || !MD5Update || !MD5Final) // Unable to check the mutex
|
||||
{
|
||||
FreeLibrary(hCryptDll);
|
||||
*hMutex = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
std::wstring cmdLine = GetCommandLine();
|
||||
std::transform(cmdLine.begin(), cmdLine.end(), cmdLine.begin(), ::towlower);
|
||||
|
||||
MD5_CTX ctx = {0};
|
||||
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, (LPBYTE)cmdLine.c_str(), cmdLine.length() * sizeof(WCHAR));
|
||||
MD5Final(&ctx);
|
||||
|
||||
FreeLibrary(hCryptDll);
|
||||
|
||||
// Convert MD5 digest to mutex string (e.g. "Rainmeter@0123456789abcdef0123456789abcdef")
|
||||
const WCHAR szHexTable[] = L"0123456789abcdef";
|
||||
WCHAR szMutex[64] = {0};
|
||||
wcscpy(szMutex, L"Rainmeter@");
|
||||
|
||||
WCHAR* pos = szMutex + wcslen(szMutex);
|
||||
|
||||
for (size_t i = 0; i < 16; ++i)
|
||||
{
|
||||
*(pos++) = *(szHexTable + ((ctx.digest[i] >> 4) & 0xF));
|
||||
*(pos++) = *(szHexTable + (ctx.digest[i] & 0xF));
|
||||
}
|
||||
|
||||
// Create mutex
|
||||
HANDLE hMutexTemp = CreateMutex(NULL, FALSE, szMutex);
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
// Rainmeter.exe is already running
|
||||
*hMutex = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Rainmeter.exe is not running
|
||||
*hMutex = hMutexTemp;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
** MainWndProc
|
||||
**
|
||||
** The main window procedure
|
||||
**
|
||||
*/
|
||||
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(message) {
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
Quit();
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_COPYDATA:
|
||||
{
|
||||
COPYDATASTRUCT* pCopyDataStruct = (COPYDATASTRUCT*) lParam;
|
||||
if (pCopyDataStruct && (pCopyDataStruct->dwData == 1) && (pCopyDataStruct->cbData > 0))
|
||||
{
|
||||
ExecuteBang((const WCHAR*)pCopyDataStruct->lpData);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return RainmeterMain(hInstance, lpCmdLine);
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "StdAfx.h"
|
||||
#include "Dialog.h"
|
||||
|
||||
HWND CDialog::c_ActiveDialog = NULL;
|
||||
|
||||
/*
|
||||
** CDialog
|
||||
**
|
||||
@ -51,12 +53,12 @@ CDialog::~CDialog()
|
||||
DeleteObject(m_FontBold);
|
||||
}
|
||||
|
||||
/*
|
||||
** SetRTL
|
||||
**
|
||||
** Enables RTL layout.
|
||||
**
|
||||
*/
|
||||
INT_PTR CDialog::OnActivate(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
c_ActiveDialog = wParam ? m_Window : NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CDialog::SetDialogRTL()
|
||||
{
|
||||
SetWindowLong(m_Window, GWL_EXSTYLE, GetWindowLong(m_Window, GWL_EXSTYLE) | WS_EX_LAYOUTRTL);
|
||||
@ -122,5 +124,6 @@ void CDialog::CTab::Activate()
|
||||
Initialize();
|
||||
}
|
||||
|
||||
EnableWindow(m_Window, TRUE);
|
||||
BringWindowToTop(m_Window);
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ class CDialog
|
||||
public:
|
||||
HWND GetWindow() { return m_Window; }
|
||||
|
||||
static HWND GetActiveDialog() { return c_ActiveDialog; }
|
||||
|
||||
protected:
|
||||
class CTab
|
||||
{
|
||||
@ -46,6 +48,8 @@ protected:
|
||||
CDialog(HWND wnd);
|
||||
virtual ~CDialog();
|
||||
|
||||
INT_PTR OnActivate(WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void SetDialogRTL();
|
||||
void SetDialogFont();
|
||||
|
||||
@ -55,6 +59,8 @@ protected:
|
||||
|
||||
private:
|
||||
static BOOL CALLBACK SetFontProc(HWND hWnd, LPARAM lParam);
|
||||
|
||||
static HWND c_ActiveDialog;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -177,6 +177,9 @@ INT_PTR CALLBACK CDialogAbout::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_ACTIVATE:
|
||||
return c_Dialog->OnActivate(wParam, lParam);
|
||||
|
||||
case WM_COMMAND:
|
||||
return c_Dialog->OnCommand(wParam, lParam);
|
||||
|
||||
@ -241,6 +244,9 @@ INT_PTR CALLBACK CDialogAbout::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
||||
|
||||
INT_PTR CDialogAbout::OnInitDialog(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HWND item = GetDlgItem(m_Window, IDCLOSE);
|
||||
SendMessage(m_Window, WM_NEXTDLGCTL, (WPARAM)item, TRUE);
|
||||
|
||||
HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_RAINMETER), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
|
||||
SendMessage(m_Window, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
|
||||
@ -250,7 +256,7 @@ INT_PTR CDialogAbout::OnInitDialog(WPARAM wParam, LPARAM lParam)
|
||||
SetDialogRTL();
|
||||
}
|
||||
|
||||
HWND item = GetDlgItem(m_Window, IDC_ABOUT_TAB);
|
||||
item = GetDlgItem(m_Window, IDC_ABOUT_TAB);
|
||||
TCITEM tci = {0};
|
||||
tci.mask = TCIF_TEXT;
|
||||
tci.pszText = GetString(ID_STR_LOG);
|
||||
@ -276,7 +282,7 @@ INT_PTR CDialogAbout::OnInitDialog(WPARAM wParam, LPARAM lParam)
|
||||
|
||||
SetWindowPlacement(m_Window, &c_WindowPlacement);
|
||||
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CDialogAbout::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
@ -302,6 +308,12 @@ INT_PTR CDialogAbout::OnNotify(WPARAM wParam, LPARAM lParam)
|
||||
case IDC_ABOUT_TAB:
|
||||
if (nm->code == TCN_SELCHANGE)
|
||||
{
|
||||
// Disable all tab windows first
|
||||
EnableWindow(m_TabLog.GetWindow(), FALSE);
|
||||
EnableWindow(m_TabMeasures.GetWindow(), FALSE);
|
||||
EnableWindow(m_TabPlugins.GetWindow(), FALSE);
|
||||
EnableWindow(m_TabVersion.GetWindow(), FALSE);
|
||||
|
||||
int sel = TabCtrl_GetCurSel(nm->hwndFrom);
|
||||
if (sel == 0)
|
||||
{
|
||||
|
@ -192,6 +192,9 @@ INT_PTR CALLBACK CDialogManage::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_ACTIVATE:
|
||||
return c_Dialog->OnActivate(wParam, lParam);
|
||||
|
||||
case WM_COMMAND:
|
||||
return c_Dialog->OnCommand(wParam, lParam);
|
||||
|
||||
@ -223,6 +226,9 @@ INT_PTR CALLBACK CDialogManage::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
|
||||
|
||||
INT_PTR CDialogManage::OnInitDialog(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HWND item = GetDlgItem(m_Window, IDCLOSE);
|
||||
SendMessage(m_Window, WM_NEXTDLGCTL, (WPARAM)item, TRUE);
|
||||
|
||||
HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_RAINMETER), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
|
||||
SendMessage(m_Window, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
|
||||
@ -232,7 +238,7 @@ INT_PTR CDialogManage::OnInitDialog(WPARAM wParam, LPARAM lParam)
|
||||
SetDialogRTL();
|
||||
}
|
||||
|
||||
HWND item = GetDlgItem(m_Window, IDC_MANAGE_TAB);
|
||||
item = GetDlgItem(m_Window, IDC_MANAGE_TAB);
|
||||
TCITEM tci = {0};
|
||||
tci.mask = TCIF_TEXT;
|
||||
tci.pszText = GetString(ID_STR_SKINS);
|
||||
@ -263,7 +269,7 @@ INT_PTR CDialogManage::OnInitDialog(WPARAM wParam, LPARAM lParam)
|
||||
|
||||
SetWindowPlacement(m_Window, &c_WindowPlacement);
|
||||
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CDialogManage::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
@ -306,6 +312,11 @@ INT_PTR CDialogManage::OnNotify(WPARAM wParam, LPARAM lParam)
|
||||
case IDC_MANAGE_TAB:
|
||||
if (nm->code == TCN_SELCHANGE)
|
||||
{
|
||||
// Disable all tab windows first
|
||||
EnableWindow(m_TabSkins.GetWindow(), FALSE);
|
||||
EnableWindow(m_TabThemes.GetWindow(), FALSE);
|
||||
EnableWindow(m_TabSettings.GetWindow(), FALSE);
|
||||
|
||||
int sel = TabCtrl_GetCurSel(nm->hwndFrom);
|
||||
if (sel == 0)
|
||||
{
|
||||
@ -1730,24 +1741,24 @@ INT_PTR CDialogManage::CTabSettings::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
SendMessage(CDialogAbout::c_Dialog->GetWindow(), WM_DELAYED_CLOSE, 0, 0);
|
||||
if (sel == 0)
|
||||
{
|
||||
ExecuteBang(L"!About"); // Delayed execute
|
||||
Rainmeter->DelayedExecuteCommand(L"!About");
|
||||
}
|
||||
else if (sel == 1)
|
||||
{
|
||||
ExecuteBang(L"!About Measures"); // Delayed execute
|
||||
Rainmeter->DelayedExecuteCommand(L"!About Measures");
|
||||
}
|
||||
else if (sel == 2)
|
||||
{
|
||||
ExecuteBang(L"!About Plugins"); // Delayed execute
|
||||
Rainmeter->DelayedExecuteCommand(L"!About Plugins");
|
||||
}
|
||||
else //if (sel == 3)
|
||||
{
|
||||
ExecuteBang(L"!About Version"); // Delayed execute
|
||||
Rainmeter->DelayedExecuteCommand(L"!About Version");
|
||||
}
|
||||
}
|
||||
|
||||
SendMessage(c_Dialog->GetWindow(), WM_DELAYED_CLOSE, 0, 0);
|
||||
ExecuteBang(L"!Manage Settings"); // Delayed execute
|
||||
Rainmeter->DelayedExecuteCommand(L"!Manage Settings");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -10,9 +10,7 @@ EXPORTS
|
||||
PluginBridge
|
||||
|
||||
; Private
|
||||
Initialize @1 NONAME
|
||||
Quit @2 NONAME
|
||||
ExecuteBang @3 NONAME
|
||||
pcre_compile @4 NONAME
|
||||
pcre_exec @5 NONAME
|
||||
pcre_study @6 NONAME
|
||||
RainmeterMain @1 NONAME
|
||||
pcre_compile @2 NONAME
|
||||
pcre_exec @3 NONAME
|
||||
pcre_study @4 NONAME
|
||||
|
@ -36,62 +36,71 @@ using namespace Gdiplus;
|
||||
CRainmeter* Rainmeter; // The module
|
||||
|
||||
/*
|
||||
** Initialize
|
||||
** RainmeterMain
|
||||
**
|
||||
** Initializes Rainmeter
|
||||
** Initializes Rainmeter.
|
||||
**
|
||||
*/
|
||||
int Initialize(HWND hWnd, HINSTANCE hInstance, LPCWSTR lpCmdLine)
|
||||
int RainmeterMain(HINSTANCE hInstance, LPWSTR cmdLine)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
try
|
||||
HWND wnd = NULL;
|
||||
while (wnd = FindWindowEx(NULL, wnd, RAINMETER_CLASS_NAME, RAINMETER_WINDOW_NAME))
|
||||
{
|
||||
Rainmeter = new CRainmeter;
|
||||
COPYDATASTRUCT cds;
|
||||
|
||||
if (Rainmeter)
|
||||
if (cmdLine && cmdLine[0] == L'!')
|
||||
{
|
||||
result = Rainmeter->Initialize(hWnd, hInstance, lpCmdLine);
|
||||
// Deliver bang to existing Rainmeter instance
|
||||
cds.dwData = 1;
|
||||
cds.cbData = (DWORD)((wcslen(cmdLine) + 1) * sizeof(WCHAR));
|
||||
cds.lpData = (PVOID)cmdLine;
|
||||
SendMessage(wnd, WM_COPYDATA, NULL, (LPARAM)&cds);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const WCHAR* fullCmdLine = GetCommandLine();
|
||||
|
||||
COPYDATASTRUCT cds;
|
||||
cds.dwData = SIZE_MAX;
|
||||
cds.cbData = (DWORD)((wcslen(fullCmdLine) + 1) * sizeof(WCHAR));
|
||||
cds.lpData = (PVOID)fullCmdLine;
|
||||
|
||||
if (SendMessage(wnd, WM_COPYDATA, NULL, (LPARAM)&cds) == SIZE_MAX)
|
||||
{
|
||||
// An instance of Rainmeter with same command-line arguments already exists
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CError& error)
|
||||
|
||||
// Avoid loading a dll from current directory
|
||||
SetDllDirectory(L"");
|
||||
|
||||
int ret = 1;
|
||||
Rainmeter = new CRainmeter;
|
||||
if (Rainmeter)
|
||||
{
|
||||
try
|
||||
{
|
||||
ret = Rainmeter->Initialize(hInstance, cmdLine);
|
||||
}
|
||||
catch (CError& error)
|
||||
{
|
||||
MessageBox(NULL, error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONERROR);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = Rainmeter->MessagePump();
|
||||
}
|
||||
|
||||
delete Rainmeter;
|
||||
Rainmeter = NULL;
|
||||
MessageBox(hWnd, error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONERROR);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
** Quit
|
||||
**
|
||||
** Quits Rainmeter.
|
||||
**
|
||||
*/
|
||||
void Quit()
|
||||
{
|
||||
delete Rainmeter;
|
||||
Rainmeter = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** ExecuteBang
|
||||
**
|
||||
** Runs a bang command. This is called from the main application
|
||||
** when a command is given as a command line argument.
|
||||
**
|
||||
*/
|
||||
void ExecuteBang(LPCTSTR szBang)
|
||||
{
|
||||
if (szBang)
|
||||
{
|
||||
// ExecuteBang needs to be delayed since it crashes if done during processing.
|
||||
// The receiver must free a given string buffer (lParam) by using free().
|
||||
WCHAR* bang = _wcsdup(szBang);
|
||||
PostMessage(Rainmeter->GetTrayWindow()->GetWindow(), WM_TRAY_DELAYED_EXECUTE, (WPARAM)NULL, (LPARAM)bang);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -708,10 +717,32 @@ CRainmeter::~CRainmeter()
|
||||
** May throw CErrors !!!!
|
||||
**
|
||||
*/
|
||||
int CRainmeter::Initialize(HWND hParent, HINSTANCE hInstance, LPCWSTR szPath)
|
||||
int CRainmeter::Initialize(HINSTANCE hInstance, LPCWSTR szPath)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
WNDCLASS wc = {0};
|
||||
wc.lpfnWndProc = (WNDPROC)MainWndProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.lpszClassName = RAINMETER_CLASS_NAME;
|
||||
RegisterClass(&wc);
|
||||
|
||||
m_Window = CreateWindowEx(
|
||||
WS_EX_TOOLWINDOW,
|
||||
RAINMETER_CLASS_NAME,
|
||||
RAINMETER_WINDOW_NAME,
|
||||
WS_POPUP | WS_DISABLED,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
hInstance,
|
||||
NULL);
|
||||
|
||||
if (!m_Window) return 1;
|
||||
|
||||
m_Instance = hInstance;
|
||||
|
||||
WCHAR* tmpSzPath = new WCHAR[MAX_LINE_LENGTH];
|
||||
@ -998,6 +1029,61 @@ int CRainmeter::Initialize(HWND hParent, HINSTANCE hInstance, LPCWSTR szPath)
|
||||
return result; // All is OK
|
||||
}
|
||||
|
||||
int CRainmeter::MessagePump()
|
||||
{
|
||||
MSG msg;
|
||||
BOOL ret;
|
||||
|
||||
// Run the standard window message loop
|
||||
while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
|
||||
{
|
||||
if (ret == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (!CDialog::GetActiveDialog() || !IsDialogMessage(CDialog::GetActiveDialog(), &msg))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK CRainmeter::MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
case WM_COPYDATA:
|
||||
{
|
||||
COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam;
|
||||
if (cds)
|
||||
{
|
||||
const WCHAR* data = (const WCHAR*)cds->lpData;
|
||||
if (cds->dwData == 1 && (cds->cbData > 0))
|
||||
{
|
||||
Rainmeter->DelayedExecuteCommand(data);
|
||||
}
|
||||
else if (cds->dwData == SIZE_MAX && _wcsicmp(GetCommandLine(), data) == 0)
|
||||
{
|
||||
return SIZE_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** CreateDefaultConfigFile
|
||||
**
|
||||
@ -1951,6 +2037,19 @@ void CRainmeter::ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** DelayedExecuteCommand
|
||||
**
|
||||
** Executes command when current processing is done.
|
||||
**
|
||||
*/
|
||||
void CRainmeter::DelayedExecuteCommand(const WCHAR* command)
|
||||
{
|
||||
WCHAR* bang = _wcsdup(command);
|
||||
PostMessage(m_TrayWindow->GetWindow(), WM_TRAY_DELAYED_EXECUTE, (WPARAM)NULL, (LPARAM)bang);
|
||||
}
|
||||
|
||||
/*
|
||||
** ReadGeneralSettings
|
||||
**
|
||||
|
@ -39,6 +39,9 @@
|
||||
#define WIDEN(x) WIDEN2(x)
|
||||
#define APPDATE WIDEN(__DATE__)
|
||||
|
||||
#define RAINMETER_CLASS_NAME L"DummyRainWClass"
|
||||
#define RAINMETER_WINDOW_NAME L"Rainmeter control window"
|
||||
|
||||
struct GlobalConfig
|
||||
{
|
||||
double netInSpeed;
|
||||
@ -114,7 +117,8 @@ public:
|
||||
CRainmeter();
|
||||
~CRainmeter();
|
||||
|
||||
int Initialize(HWND hParent, HINSTANCE hInstance, LPCWSTR szPath);
|
||||
int Initialize(HINSTANCE hInstance, LPCWSTR szPath);
|
||||
int MessagePump();
|
||||
|
||||
CConfigParser* GetCurrentParser() { return m_CurrentParser; }
|
||||
void SetCurrentParser(CConfigParser* parser) { m_CurrentParser = parser; }
|
||||
@ -153,6 +157,8 @@ public:
|
||||
const std::wstring& GetLogViewer() { return m_LogViewer; }
|
||||
const std::wstring& GetStatsDate() { return m_StatsDate; }
|
||||
|
||||
HWND GetWindow() { return m_Window; }
|
||||
|
||||
HINSTANCE GetInstance() { return m_Instance; }
|
||||
HINSTANCE GetResourceInstance() { return m_ResourceInstance; }
|
||||
LCID GetResourceLCID() { return m_ResourceLCID; }
|
||||
@ -201,6 +207,7 @@ public:
|
||||
const std::wstring& GetTrayExecuteDM() { return m_TrayExecuteDM; }
|
||||
|
||||
void ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow);
|
||||
void DelayedExecuteCommand(const WCHAR* command);
|
||||
|
||||
void RefreshAll();
|
||||
|
||||
@ -214,6 +221,8 @@ public:
|
||||
friend class CDialogManage;
|
||||
|
||||
private:
|
||||
static LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs, CMeterWindow* meterWindow);
|
||||
void BangGroupWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs, CMeterWindow* meterWindow);
|
||||
void Bang_ActivateConfig(const WCHAR* arg);
|
||||
@ -301,6 +310,8 @@ private:
|
||||
|
||||
CConfigParser* m_CurrentParser;
|
||||
|
||||
HWND m_Window;
|
||||
|
||||
HINSTANCE m_Instance;
|
||||
HMODULE m_ResourceInstance;
|
||||
LCID m_ResourceLCID;
|
||||
@ -316,8 +327,6 @@ private:
|
||||
#define EXPORT_PLUGIN EXTERN_C __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
EXPORT_PLUGIN int Initialize(HWND hWnd, HINSTANCE hInstance, LPCWSTR lpCmdLine);
|
||||
EXPORT_PLUGIN void Quit();
|
||||
EXPORT_PLUGIN void ExecuteBang(LPCTSTR szBang);
|
||||
EXPORT_PLUGIN int RainmeterMain(HINSTANCE Instance, LPWSTR cmdLine);
|
||||
|
||||
#endif
|
||||
|
@ -476,7 +476,6 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
else if (wParam == ID_CONTEXT_QUIT)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
Quit();
|
||||
}
|
||||
else if (wParam == ID_CONTEXT_OPENSKINSFOLDER)
|
||||
{
|
||||
@ -583,7 +582,7 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
{
|
||||
COPYDATASTRUCT cds;
|
||||
cds.dwData = wParam;
|
||||
cds.cbData = (DWORD)((data.length() + 1) + sizeof(WCHAR));
|
||||
cds.cbData = (DWORD)((data.length() + 1) * sizeof(WCHAR));
|
||||
cds.lpData = (PVOID)data.c_str();
|
||||
SendMessage((HWND)lParam, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user