- 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:
Birunthan Mohanathas 2012-02-14 17:00:07 +00:00
parent 4d814bbd58
commit 2c6ed8ed69
9 changed files with 212 additions and 360 deletions

View File

@ -17,10 +17,9 @@
*/ */
#define _CRTDBG_MAP_ALLOC #define _CRTDBG_MAP_ALLOC
#include <stdlib.h> #define WIN32_LEAN_AND_MEAN
#include <crtdbg.h> #include <crtdbg.h>
#include <string> #include <Windows.h>
#include <algorithm>
#include "../Library/Rainmeter.h" #include "../Library/Rainmeter.h"
#if defined _M_IX86 #if defined _M_IX86
@ -34,296 +33,12 @@
#endif #endif
/* /*
** Protos ** wWinMain
*/
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
** **
** The Main-function ** Entry point.
** **
*/ */
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{ {
HANDLE hMutex = NULL; return RainmeterMain(hInstance, lpCmdLine);
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)&copyData);
}
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;
} }

View File

@ -19,6 +19,8 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "Dialog.h" #include "Dialog.h"
HWND CDialog::c_ActiveDialog = NULL;
/* /*
** CDialog ** CDialog
** **
@ -51,12 +53,12 @@ CDialog::~CDialog()
DeleteObject(m_FontBold); DeleteObject(m_FontBold);
} }
/* INT_PTR CDialog::OnActivate(WPARAM wParam, LPARAM lParam)
** SetRTL {
** c_ActiveDialog = wParam ? m_Window : NULL;
** Enables RTL layout. return FALSE;
** }
*/
void CDialog::SetDialogRTL() void CDialog::SetDialogRTL()
{ {
SetWindowLong(m_Window, GWL_EXSTYLE, GetWindowLong(m_Window, GWL_EXSTYLE) | WS_EX_LAYOUTRTL); SetWindowLong(m_Window, GWL_EXSTYLE, GetWindowLong(m_Window, GWL_EXSTYLE) | WS_EX_LAYOUTRTL);
@ -122,5 +124,6 @@ void CDialog::CTab::Activate()
Initialize(); Initialize();
} }
EnableWindow(m_Window, TRUE);
BringWindowToTop(m_Window); BringWindowToTop(m_Window);
} }

View File

@ -24,6 +24,8 @@ class CDialog
public: public:
HWND GetWindow() { return m_Window; } HWND GetWindow() { return m_Window; }
static HWND GetActiveDialog() { return c_ActiveDialog; }
protected: protected:
class CTab class CTab
{ {
@ -46,6 +48,8 @@ protected:
CDialog(HWND wnd); CDialog(HWND wnd);
virtual ~CDialog(); virtual ~CDialog();
INT_PTR OnActivate(WPARAM wParam, LPARAM lParam);
void SetDialogRTL(); void SetDialogRTL();
void SetDialogFont(); void SetDialogFont();
@ -55,6 +59,8 @@ protected:
private: private:
static BOOL CALLBACK SetFontProc(HWND hWnd, LPARAM lParam); static BOOL CALLBACK SetFontProc(HWND hWnd, LPARAM lParam);
static HWND c_ActiveDialog;
}; };
#endif #endif

View File

@ -177,6 +177,9 @@ INT_PTR CALLBACK CDialogAbout::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
{ {
switch (uMsg) switch (uMsg)
{ {
case WM_ACTIVATE:
return c_Dialog->OnActivate(wParam, lParam);
case WM_COMMAND: case WM_COMMAND:
return c_Dialog->OnCommand(wParam, lParam); 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) 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); 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); SendMessage(m_Window, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
@ -250,7 +256,7 @@ INT_PTR CDialogAbout::OnInitDialog(WPARAM wParam, LPARAM lParam)
SetDialogRTL(); SetDialogRTL();
} }
HWND item = GetDlgItem(m_Window, IDC_ABOUT_TAB); item = GetDlgItem(m_Window, IDC_ABOUT_TAB);
TCITEM tci = {0}; TCITEM tci = {0};
tci.mask = TCIF_TEXT; tci.mask = TCIF_TEXT;
tci.pszText = GetString(ID_STR_LOG); tci.pszText = GetString(ID_STR_LOG);
@ -276,7 +282,7 @@ INT_PTR CDialogAbout::OnInitDialog(WPARAM wParam, LPARAM lParam)
SetWindowPlacement(m_Window, &c_WindowPlacement); SetWindowPlacement(m_Window, &c_WindowPlacement);
return TRUE; return FALSE;
} }
INT_PTR CDialogAbout::OnCommand(WPARAM wParam, LPARAM lParam) INT_PTR CDialogAbout::OnCommand(WPARAM wParam, LPARAM lParam)
@ -302,6 +308,12 @@ INT_PTR CDialogAbout::OnNotify(WPARAM wParam, LPARAM lParam)
case IDC_ABOUT_TAB: case IDC_ABOUT_TAB:
if (nm->code == TCN_SELCHANGE) 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); int sel = TabCtrl_GetCurSel(nm->hwndFrom);
if (sel == 0) if (sel == 0)
{ {

View File

@ -192,6 +192,9 @@ INT_PTR CALLBACK CDialogManage::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
{ {
switch (uMsg) switch (uMsg)
{ {
case WM_ACTIVATE:
return c_Dialog->OnActivate(wParam, lParam);
case WM_COMMAND: case WM_COMMAND:
return c_Dialog->OnCommand(wParam, lParam); 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) 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); 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); SendMessage(m_Window, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
@ -232,7 +238,7 @@ INT_PTR CDialogManage::OnInitDialog(WPARAM wParam, LPARAM lParam)
SetDialogRTL(); SetDialogRTL();
} }
HWND item = GetDlgItem(m_Window, IDC_MANAGE_TAB); item = GetDlgItem(m_Window, IDC_MANAGE_TAB);
TCITEM tci = {0}; TCITEM tci = {0};
tci.mask = TCIF_TEXT; tci.mask = TCIF_TEXT;
tci.pszText = GetString(ID_STR_SKINS); tci.pszText = GetString(ID_STR_SKINS);
@ -263,7 +269,7 @@ INT_PTR CDialogManage::OnInitDialog(WPARAM wParam, LPARAM lParam)
SetWindowPlacement(m_Window, &c_WindowPlacement); SetWindowPlacement(m_Window, &c_WindowPlacement);
return TRUE; return FALSE;
} }
INT_PTR CDialogManage::OnCommand(WPARAM wParam, LPARAM lParam) INT_PTR CDialogManage::OnCommand(WPARAM wParam, LPARAM lParam)
@ -306,6 +312,11 @@ INT_PTR CDialogManage::OnNotify(WPARAM wParam, LPARAM lParam)
case IDC_MANAGE_TAB: case IDC_MANAGE_TAB:
if (nm->code == TCN_SELCHANGE) 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); int sel = TabCtrl_GetCurSel(nm->hwndFrom);
if (sel == 0) 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); SendMessage(CDialogAbout::c_Dialog->GetWindow(), WM_DELAYED_CLOSE, 0, 0);
if (sel == 0) if (sel == 0)
{ {
ExecuteBang(L"!About"); // Delayed execute Rainmeter->DelayedExecuteCommand(L"!About");
} }
else if (sel == 1) else if (sel == 1)
{ {
ExecuteBang(L"!About Measures"); // Delayed execute Rainmeter->DelayedExecuteCommand(L"!About Measures");
} }
else if (sel == 2) else if (sel == 2)
{ {
ExecuteBang(L"!About Plugins"); // Delayed execute Rainmeter->DelayedExecuteCommand(L"!About Plugins");
} }
else //if (sel == 3) else //if (sel == 3)
{ {
ExecuteBang(L"!About Version"); // Delayed execute Rainmeter->DelayedExecuteCommand(L"!About Version");
} }
} }
SendMessage(c_Dialog->GetWindow(), WM_DELAYED_CLOSE, 0, 0); SendMessage(c_Dialog->GetWindow(), WM_DELAYED_CLOSE, 0, 0);
ExecuteBang(L"!Manage Settings"); // Delayed execute Rainmeter->DelayedExecuteCommand(L"!Manage Settings");
} }
} }
break; break;

View File

@ -10,9 +10,7 @@ EXPORTS
PluginBridge PluginBridge
; Private ; Private
Initialize @1 NONAME RainmeterMain @1 NONAME
Quit @2 NONAME pcre_compile @2 NONAME
ExecuteBang @3 NONAME pcre_exec @3 NONAME
pcre_compile @4 NONAME pcre_study @4 NONAME
pcre_exec @5 NONAME
pcre_study @6 NONAME

View File

@ -36,62 +36,71 @@ using namespace Gdiplus;
CRainmeter* Rainmeter; // The module 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; HWND wnd = NULL;
while (wnd = FindWindowEx(NULL, wnd, RAINMETER_CLASS_NAME, RAINMETER_WINDOW_NAME))
try
{ {
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; delete Rainmeter;
Rainmeter = NULL; Rainmeter = NULL;
MessageBox(hWnd, error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONERROR);
} }
return result; return ret;
}
/*
** 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);
}
} }
/* /*
@ -708,10 +717,32 @@ CRainmeter::~CRainmeter()
** May throw CErrors !!!! ** May throw CErrors !!!!
** **
*/ */
int CRainmeter::Initialize(HWND hParent, HINSTANCE hInstance, LPCWSTR szPath) int CRainmeter::Initialize(HINSTANCE hInstance, LPCWSTR szPath)
{ {
int result = 0; 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; m_Instance = hInstance;
WCHAR* tmpSzPath = new WCHAR[MAX_LINE_LENGTH]; 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 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 ** 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 ** ReadGeneralSettings
** **

View File

@ -39,6 +39,9 @@
#define WIDEN(x) WIDEN2(x) #define WIDEN(x) WIDEN2(x)
#define APPDATE WIDEN(__DATE__) #define APPDATE WIDEN(__DATE__)
#define RAINMETER_CLASS_NAME L"DummyRainWClass"
#define RAINMETER_WINDOW_NAME L"Rainmeter control window"
struct GlobalConfig struct GlobalConfig
{ {
double netInSpeed; double netInSpeed;
@ -114,7 +117,8 @@ public:
CRainmeter(); CRainmeter();
~CRainmeter(); ~CRainmeter();
int Initialize(HWND hParent, HINSTANCE hInstance, LPCWSTR szPath); int Initialize(HINSTANCE hInstance, LPCWSTR szPath);
int MessagePump();
CConfigParser* GetCurrentParser() { return m_CurrentParser; } CConfigParser* GetCurrentParser() { return m_CurrentParser; }
void SetCurrentParser(CConfigParser* parser) { m_CurrentParser = parser; } void SetCurrentParser(CConfigParser* parser) { m_CurrentParser = parser; }
@ -153,6 +157,8 @@ public:
const std::wstring& GetLogViewer() { return m_LogViewer; } const std::wstring& GetLogViewer() { return m_LogViewer; }
const std::wstring& GetStatsDate() { return m_StatsDate; } const std::wstring& GetStatsDate() { return m_StatsDate; }
HWND GetWindow() { return m_Window; }
HINSTANCE GetInstance() { return m_Instance; } HINSTANCE GetInstance() { return m_Instance; }
HINSTANCE GetResourceInstance() { return m_ResourceInstance; } HINSTANCE GetResourceInstance() { return m_ResourceInstance; }
LCID GetResourceLCID() { return m_ResourceLCID; } LCID GetResourceLCID() { return m_ResourceLCID; }
@ -201,6 +207,7 @@ public:
const std::wstring& GetTrayExecuteDM() { return m_TrayExecuteDM; } const std::wstring& GetTrayExecuteDM() { return m_TrayExecuteDM; }
void ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow); void ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow);
void DelayedExecuteCommand(const WCHAR* command);
void RefreshAll(); void RefreshAll();
@ -214,6 +221,8 @@ public:
friend class CDialogManage; friend class CDialogManage;
private: 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 BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs, CMeterWindow* meterWindow);
void BangGroupWithArgs(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); void Bang_ActivateConfig(const WCHAR* arg);
@ -301,6 +310,8 @@ private:
CConfigParser* m_CurrentParser; CConfigParser* m_CurrentParser;
HWND m_Window;
HINSTANCE m_Instance; HINSTANCE m_Instance;
HMODULE m_ResourceInstance; HMODULE m_ResourceInstance;
LCID m_ResourceLCID; LCID m_ResourceLCID;
@ -316,8 +327,6 @@ private:
#define EXPORT_PLUGIN EXTERN_C __declspec(dllimport) #define EXPORT_PLUGIN EXTERN_C __declspec(dllimport)
#endif #endif
EXPORT_PLUGIN int Initialize(HWND hWnd, HINSTANCE hInstance, LPCWSTR lpCmdLine); EXPORT_PLUGIN int RainmeterMain(HINSTANCE Instance, LPWSTR cmdLine);
EXPORT_PLUGIN void Quit();
EXPORT_PLUGIN void ExecuteBang(LPCTSTR szBang);
#endif #endif

View File

@ -476,7 +476,6 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
else if (wParam == ID_CONTEXT_QUIT) else if (wParam == ID_CONTEXT_QUIT)
{ {
PostQuitMessage(0); PostQuitMessage(0);
Quit();
} }
else if (wParam == ID_CONTEXT_OPENSKINSFOLDER) else if (wParam == ID_CONTEXT_OPENSKINSFOLDER)
{ {
@ -583,7 +582,7 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
{ {
COPYDATASTRUCT cds; COPYDATASTRUCT cds;
cds.dwData = wParam; 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(); cds.lpData = (PVOID)data.c_str();
SendMessage((HWND)lParam, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds); SendMessage((HWND)lParam, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
}; };