mirror of https://github.com/roytam1/kmeleon.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
437 lines
12 KiB
437 lines
12 KiB
/* |
|
* Copyright (C) 2000 Brian Harris |
|
* |
|
* This program is free software; you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation; either version 2, or (at your option) |
|
* any later version. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program; if not, write to the Free Software |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|
*/ |
|
// weasel.cpp : Defines the entry point for the DLL application. |
|
// |
|
|
|
#include "stdafx.h" |
|
|
|
#include "resource.h" |
|
|
|
#include <vector> |
|
|
|
typedef std::vector<HWND> hwndVector; |
|
|
|
#define KMELEON_PLUGIN_EXPORTS |
|
#include "../kmeleon_plugin.h" |
|
|
|
#include "pop.h" |
|
|
|
#define PLUGIN_NAME "Weasel Email Plugin" |
|
|
|
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) |
|
{ |
|
switch (ul_reason_for_call) |
|
{ |
|
case DLL_PROCESS_ATTACH: |
|
case DLL_THREAD_ATTACH: |
|
case DLL_THREAD_DETACH: |
|
case DLL_PROCESS_DETACH: |
|
break; |
|
} |
|
|
|
return TRUE; |
|
} |
|
|
|
int Init(); |
|
void Create(HWND parent); |
|
void Config(HWND parent); |
|
void Quit(); |
|
void DoMenu(HMENU menu, char *param); |
|
void DoRebar(HWND rebarWnd); |
|
|
|
pluginFunctions pFunc = { |
|
Init, |
|
Create, |
|
Config, |
|
Quit, |
|
DoMenu, |
|
DoRebar |
|
}; |
|
|
|
kmeleonPlugin kPlugin = { |
|
KMEL_PLUGIN_VER, |
|
PLUGIN_NAME, |
|
&pFunc |
|
}; |
|
|
|
static DWORD WINAPI MainThread( LPVOID lpParameter /* thread data*/ ); |
|
static HANDLE gMainThread; |
|
|
|
static int gDie; |
|
static int gCheckNow; |
|
static int gEnabled; |
|
|
|
static HIMAGELIST gImages; |
|
|
|
static UINT gCheckID; |
|
static UINT gMailID; |
|
static UINT gConfigID; |
|
|
|
static int gNumberOfMessages; |
|
|
|
char szServerName[255]; |
|
char szUsername[255]; |
|
char szPassword[255]; |
|
|
|
char szNewMailSound[255]; |
|
|
|
int Init(){ |
|
// allocate some ids |
|
gCheckID = kPlugin.kf->GetCommandIDs(1); |
|
gMailID = kPlugin.kf->GetCommandIDs(1); |
|
gConfigID = kPlugin.kf->GetCommandIDs(1); |
|
|
|
gImages = ImageList_LoadImage(kPlugin.hDllInstance, MAKEINTRESOURCE(IDB_TOOLBAR_BUTTONS), 12, 2, CLR_DEFAULT, IMAGE_BITMAP, LR_DEFAULTCOLOR ); |
|
|
|
/* sockets */ |
|
{ |
|
WORD wVersionRequested; |
|
WSADATA wsaData; |
|
|
|
wVersionRequested = MAKEWORD( 2, 2 ); |
|
|
|
if (WSAStartup( wVersionRequested, &wsaData ) != 0){ |
|
MessageBox(NULL, "Could Not Start up Winsock!", PLUGIN_NAME " Error!", 0); |
|
return false; |
|
} |
|
} |
|
|
|
// read some configs |
|
kPlugin.kf->GetPreference(PREF_STRING, "kmeleon.mail.server", szServerName, ""); |
|
kPlugin.kf->GetPreference(PREF_STRING, "kmeleon.mail.username", szUsername, ""); |
|
kPlugin.kf->GetPreference(PREF_STRING, "kmeleon.mail.password", szPassword, ""); |
|
|
|
gEnabled = 0; |
|
kPlugin.kf->GetPreference(PREF_BOOL, "kmeleon.mail.enabled", &gEnabled, &gEnabled); |
|
|
|
kPlugin.kf->GetPreference(PREF_STRING, "kmeleon.mail.sound", szNewMailSound, "c:\\windows\\media\\ding.wav"); |
|
|
|
gDie = false; |
|
gCheckNow = true; |
|
gNumberOfMessages = 0; |
|
|
|
/* thread */ |
|
{ |
|
DWORD threadId; |
|
gMainThread = CreateThread(NULL, 0, MainThread, 0, 0, &threadId); |
|
SetThreadPriority(gMainThread, THREAD_PRIORITY_BELOW_NORMAL); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
hwndVector gWindowList; |
|
|
|
WNDPROC KMeleonWndProc; |
|
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); |
|
|
|
void Create(HWND parent){ |
|
KMeleonWndProc = (WNDPROC) GetWindowLong(parent, GWL_WNDPROC); |
|
SetWindowLong(parent, GWL_WNDPROC, (LONG)WndProc); |
|
|
|
gWindowList.push_back(parent); |
|
} |
|
|
|
CALLBACK OptionsProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); |
|
|
|
void Config(HWND parent){ |
|
DialogBoxParam(kPlugin.hDllInstance, MAKEINTRESOURCE(IDD_DIALOG1), parent, OptionsProc, 0); |
|
} |
|
|
|
void Quit(){ |
|
ImageList_Destroy(gImages); |
|
|
|
gDie = 1; |
|
// wait 3 seconds |
|
if (WaitForSingleObject(gMainThread, 3000) == WAIT_TIMEOUT){ |
|
TerminateThread(gMainThread, 0); |
|
} |
|
CloseHandle(gMainThread); |
|
WSACleanup(); |
|
} |
|
|
|
void DoMenu(HMENU menu, char *param){ |
|
AppendMenu(menu, MF_STRING, gCheckID, "Check For New Mail"); |
|
AppendMenu(menu, MF_STRING, gMailID, "Open Mail"); |
|
AppendMenu(menu, MF_STRING, gConfigID, "Config Mail"); |
|
} |
|
|
|
void DoRebar(HWND rebarWnd){ |
|
|
|
DWORD dwStyle = 0x40 | /*the 40 gets rid of an ugly border on top. I have no idea what flag it corresponds to...*/ |
|
CCS_NOPARENTALIGN | CCS_NORESIZE | |
|
TBSTYLE_FLAT | TBSTYLE_TRANSPARENT /* | TBSTYLE_AUTOSIZE | TBSTYLE_LIST | TBSTYLE_TOOLTIPS */; |
|
|
|
// Create the toolbar control to be added. |
|
HWND hwndTB = CreateWindowEx(0, TOOLBARCLASSNAME, "", |
|
WS_CHILD | dwStyle, |
|
0,0,0,0, |
|
rebarWnd, (HMENU)/*id*/200, |
|
kPlugin.hDllInstance, NULL |
|
); |
|
|
|
if (!hwndTB){ |
|
MessageBox(NULL, "Failed to create mail toolbar", NULL, 0); |
|
return; |
|
} |
|
|
|
SendMessage(hwndTB, TB_SETIMAGELIST, 0, (LPARAM)gImages); |
|
SendMessage(hwndTB, TB_SETHOTIMAGELIST, 0, (LPARAM)gImages); |
|
|
|
SendMessage(hwndTB, TB_SETBUTTONWIDTH, 0, MAKELONG(0, 100)); |
|
|
|
TBBUTTON button; |
|
button.iBitmap = (gNumberOfMessages>9?10:gNumberOfMessages); |
|
button.idCommand = gMailID; |
|
button.iString = 0; |
|
|
|
button.dwData = 0; |
|
button.fsState = TBSTATE_ENABLED; |
|
button.fsStyle = TBSTYLE_BUTTON; |
|
button.bReserved[0] = 0; |
|
|
|
SendMessage(hwndTB, TB_INSERTBUTTON, (WPARAM)0, (LPARAM)&button); |
|
|
|
// Register the band name and child hwnd |
|
kPlugin.kf->RegisterBand(hwndTB, "Weasel Email"); |
|
|
|
SetWindowText(hwndTB, "Weasel"); |
|
|
|
// Get the height of the toolbar. |
|
DWORD dwBtnSize = SendMessage(hwndTB, TB_GETBUTTONSIZE, 0,0); |
|
|
|
REBARBANDINFO rbBand; |
|
rbBand.cbSize = sizeof(REBARBANDINFO); // Required |
|
rbBand.fMask = /*RBBIM_TEXT |*/ |
|
RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | |
|
RBBIM_SIZE | RBBIM_IDEALSIZE; |
|
|
|
rbBand.fStyle = RBBS_CHILDEDGE | RBBS_FIXEDBMP | RBBS_VARIABLEHEIGHT; |
|
rbBand.lpText = "Weasel"; |
|
rbBand.hwndChild = hwndTB; |
|
rbBand.cxMinChild = 0; |
|
rbBand.cyMinChild = HIWORD(dwBtnSize); |
|
rbBand.cyIntegral = 1; |
|
rbBand.cyMaxChild = rbBand.cyMinChild; |
|
rbBand.cxIdeal = LOWORD(dwBtnSize); |
|
rbBand.cx = rbBand.cxIdeal; |
|
|
|
// Add the band that has the toolbar. |
|
SendMessage(rebarWnd, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); |
|
} |
|
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
|
{ |
|
switch (message) { |
|
case WM_COMMAND: |
|
{ |
|
WORD command = LOWORD(wParam); |
|
if (command == gCheckID){ |
|
gCheckNow = true; |
|
return true; |
|
} |
|
if (command == gMailID){ |
|
ShellExecute(hWnd, "open", "mailto:", "", "", SW_SHOWNORMAL); |
|
return true; |
|
} |
|
if (command == gConfigID){ |
|
Config(NULL); |
|
return true; |
|
} |
|
} |
|
break; |
|
case WM_CLOSE: |
|
if (gWindowList.size() == 1){ |
|
gWindowList.clear(); |
|
} |
|
else{ |
|
hwndVector::iterator window; |
|
for (window = gWindowList.begin(); window && window != gWindowList.end(); window++) { |
|
if (*window == hWnd){ |
|
gWindowList.erase(window); |
|
} |
|
} |
|
} |
|
break; |
|
} |
|
|
|
return CallWindowProc(KMeleonWndProc, hWnd, message, wParam, lParam); |
|
} |
|
|
|
void BrowseForFile(HWND hWnd, int id, char *filename, char *filter) |
|
{ |
|
OPENFILENAME ofn; // common dialog box structure |
|
char szFile[260]; |
|
strcpy(szFile, filename); |
|
|
|
// Initialize OPENFILENAME |
|
ZeroMemory(&ofn, sizeof(OPENFILENAME)); |
|
ofn.lStructSize = sizeof(OPENFILENAME); |
|
ofn.hwndOwner = hWnd; |
|
ofn.lpstrFile = szFile; |
|
ofn.nMaxFile = sizeof(szFile); |
|
ofn.lpstrFilter = filter; |
|
ofn.nFilterIndex = 1; |
|
ofn.lpstrFileTitle = NULL; |
|
ofn.nMaxFileTitle = 0; |
|
ofn.lpstrInitialDir = NULL; |
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; |
|
|
|
// Display the Open dialog box. |
|
|
|
if (GetOpenFileName(&ofn)==TRUE) |
|
SetDlgItemText(hWnd, id, ofn.lpstrFile); |
|
|
|
} |
|
|
|
CALLBACK OptionsProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
switch (uMsg){ |
|
case WM_INITDIALOG: |
|
SetDlgItemText(hDlg, IDC_EDIT_SERVER, szServerName); |
|
SetDlgItemText(hDlg, IDC_EDIT_USERNAME, szUsername); |
|
SetDlgItemText(hDlg, IDC_EDIT_PASSWORD, szPassword); |
|
CheckDlgButton(hDlg, IDC_CHECK_ENABLED, (gEnabled?BST_CHECKED:BST_UNCHECKED)); |
|
SetDlgItemText(hDlg, IDC_EDIT_SOUND, szNewMailSound); |
|
return true; |
|
case WM_COMMAND: |
|
{ |
|
if (HIWORD(wParam) == BN_CLICKED){ |
|
WORD id = LOWORD(wParam); |
|
switch(id){ |
|
case IDC_BUTTON_BROWSE: |
|
BrowseForFile(hDlg, IDC_EDIT_SOUND, szNewMailSound, "Sounds (*.wav)\0*.wav\0"); |
|
break; |
|
|
|
case IDC_BUTTON_TEST: |
|
{ |
|
char szFile[256]; |
|
GetDlgItemText(hDlg, IDC_EDIT_SOUND, szFile, 255); |
|
PlaySound(szFile, NULL, SND_FILENAME|SND_ASYNC); |
|
} |
|
break; |
|
|
|
case IDOK: |
|
GetDlgItemText(hDlg, IDC_EDIT_SERVER, szServerName, 255); |
|
GetDlgItemText(hDlg, IDC_EDIT_USERNAME, szUsername, 255); |
|
GetDlgItemText(hDlg, IDC_EDIT_PASSWORD, szPassword, 255); |
|
gEnabled = IsDlgButtonChecked(hDlg, IDC_CHECK_ENABLED); |
|
GetDlgItemText(hDlg, IDC_EDIT_SOUND, szNewMailSound, 255); |
|
|
|
kPlugin.kf->SetPreference(PREF_STRING, "kmeleon.mail.server", szServerName); |
|
kPlugin.kf->SetPreference(PREF_STRING, "kmeleon.mail.username", szUsername); |
|
kPlugin.kf->SetPreference(PREF_STRING, "kmeleon.mail.password", szPassword); |
|
kPlugin.kf->SetPreference(PREF_BOOL, "kmeleon.mail.enabled", &gEnabled); |
|
kPlugin.kf->SetPreference(PREF_STRING, "kmeleon.mail.sound", szNewMailSound); |
|
|
|
// fall through |
|
case IDCANCEL: |
|
EndDialog(hDlg, id); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
// so it doesn't munge the function name |
|
extern "C" { |
|
KMELEON_PLUGIN kmeleonPlugin *GetKmeleonPlugin() { |
|
return &kPlugin; |
|
} |
|
} |
|
|
|
void ChangeImage(int imageIndex) |
|
{ |
|
TBBUTTONINFO button; |
|
button.cbSize = sizeof(button); |
|
button.dwMask = TBIF_IMAGE; |
|
button.iImage = imageIndex; |
|
|
|
hwndVector::iterator window; |
|
for (window = gWindowList.begin(); window && window != gWindowList.end(); window++) { |
|
HWND rbWnd = FindWindowEx(*window, NULL, REBARCLASSNAME, NULL); |
|
HWND tbWnd = FindWindowEx(rbWnd, NULL, TOOLBARCLASSNAME, "Weasel"); |
|
SendMessage(tbWnd, TB_SETBUTTONINFO, gMailID, (LPARAM)&button); |
|
} |
|
} |
|
|
|
DWORD WINAPI MainThread( LPVOID lpParameter /* thread data*/ ){ |
|
int counter; |
|
|
|
CPOP pop; |
|
|
|
int previousNumOfMsgs; |
|
|
|
gDie = 0; |
|
while (!gDie){ |
|
// wait 60 seconds (do this rather than Sleep(5000) so we can check gDie) |
|
if (!gEnabled || (!gCheckNow && counter < 60)){ |
|
counter++; |
|
if (gNumberOfMessages) { |
|
if (counter % 2) { |
|
ChangeImage(gNumberOfMessages>9?10:gNumberOfMessages); |
|
} |
|
else { |
|
ChangeImage(0); |
|
} |
|
} |
|
Sleep(1000); |
|
continue; |
|
} |
|
counter = 0; |
|
gCheckNow = false; |
|
|
|
if (!pop.Setup()){ |
|
continue; |
|
} |
|
if (!pop.Connect(szServerName)){ |
|
continue; |
|
} |
|
if (!pop.Login(szUsername, szPassword)){ |
|
continue; |
|
} |
|
|
|
previousNumOfMsgs = gNumberOfMessages; |
|
gNumberOfMessages = pop.NumberOfMessages(); |
|
|
|
if (gNumberOfMessages != previousNumOfMsgs) { |
|
ChangeImage(gNumberOfMessages>9?10:gNumberOfMessages); |
|
|
|
if (gNumberOfMessages && szNewMailSound) |
|
PlaySound(szNewMailSound, NULL, SND_FILENAME|SND_ASYNC); |
|
} |
|
|
|
pop.Quit(); |
|
} |
|
return 1; |
|
} |
|
|
|
void CPOP::SocketError(char *format, ...) |
|
{ |
|
char error[255]; |
|
|
|
va_list args; |
|
va_start(args, format); |
|
vsprintf(error, format, args); |
|
va_end(args); |
|
|
|
MessageBox(NULL, error, PLUGIN_NAME " Error!", 0); |
|
}
|
|
|