summaryrefslogtreecommitdiff
path: root/plugins/TopToolBar/src/toolbar.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-24 09:26:39 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-24 09:26:39 +0000
commit1e92bf5cf72665b5fec103a0a70d734340725539 (patch)
tree7f9dc318b0e18b2cd55e2604c309eb006c11f278 /plugins/TopToolBar/src/toolbar.cpp
parentcd441faefd073cfd368d815f4237d7b4996a1063 (diff)
StopSpamPlus, TipperYM, TooltipNotify, TopToolBar, TranslitSwitcher, UserGuide: changed folder structure
git-svn-id: http://svn.miranda-ng.org/main/trunk@1159 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/TopToolBar/src/toolbar.cpp')
-rw-r--r--plugins/TopToolBar/src/toolbar.cpp707
1 files changed, 707 insertions, 0 deletions
diff --git a/plugins/TopToolBar/src/toolbar.cpp b/plugins/TopToolBar/src/toolbar.cpp
new file mode 100644
index 0000000000..156b83dbb7
--- /dev/null
+++ b/plugins/TopToolBar/src/toolbar.cpp
@@ -0,0 +1,707 @@
+
+#include "common.h"
+
+#define OLD_TBBUTTON_SIZE (offsetof(TTBButton, pszTooltipUp))
+
+pfnCustomProc g_CustomProc = NULL;
+LPARAM g_CustomProcParam = 0;
+TTBCtrl *g_ctrl = NULL;
+
+INT_PTR OnEventFire(WPARAM wParam, LPARAM lParam);
+
+HWND hwndContactList = 0;
+
+int nextButtonId = 200;
+
+HANDLE hTTBModuleLoaded, hTTBInitButtons;
+static WNDPROC buttonWndProc;
+
+CRITICAL_SECTION csButtonsHook;
+
+int sortfunc(const TopButtonInt* a, const TopButtonInt* b)
+{
+ return a->arrangedpos - b->arrangedpos;
+}
+
+LIST<TopButtonInt> Buttons(8, sortfunc);
+
+TopButtonInt* idtopos(int id, int* pPos)
+{
+ for ( int i = 0; i < Buttons.getCount(); i++)
+ if (Buttons[i]->id == id) {
+ if (pPos) *pPos = i;
+ return Buttons[i];
+ }
+
+ if (pPos) *pPos = -1;
+ return NULL;
+}
+
+//----- Service buttons -----
+void InsertSBut(int i)
+{
+ TTBButton ttb = { 0 };
+ ttb.cbSize = sizeof(ttb);
+ ttb.hIconDn = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_RUN), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ ttb.hIconUp = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_RUN), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ ttb.dwFlags = TTBBF_VISIBLE | TTBBF_ISSBUTTON | TTBBF_INTERNAL;
+ ttb.wParamDown = i;
+ TTBAddButton(( WPARAM )&ttb, 0);
+}
+
+void LoadAllSButs()
+{
+ //must be locked
+ int cnt = db_get_b(0, TTB_OPTDIR, "ServiceCnt", 0);
+ if (cnt > 0) {
+ for (int i = 1; i<=cnt; i++)
+ InsertSBut(i);
+ }
+}
+
+//----- Launch buttons -----
+INT_PTR LaunchService(WPARAM wParam, LPARAM lParam)
+{
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si = {0};
+ si.cb = sizeof(si);
+
+ if ( CreateProcess(NULL, Buttons[lParam]->ptszProgram, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+
+ return 0;
+}
+
+void InsertLBut(int i)
+{
+ TTBButton ttb = { 0 };
+ ttb.cbSize = sizeof(ttb);
+ ttb.hIconDn = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_RUN), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ ttb.dwFlags = TTBBF_VISIBLE | TTBBF_ISLBUTTON | TTBBF_INTERNAL;
+ ttb.name = LPGEN("Default");
+ ttb.program = _T("Execute Path");
+ ttb.wParamDown = i;
+ TTBAddButton(( WPARAM )&ttb, 0);
+}
+
+void LoadAllLButs()
+{
+ //must be locked
+ int cnt = db_get_b(0, TTB_OPTDIR, "LaunchCnt", 0);
+ for (int i = 0; i < cnt; i++)
+ InsertLBut(i);
+}
+
+//----- Separators -----
+
+void InsertSeparator(int i)
+{
+ TTBButton ttb = { 0 };
+ ttb.cbSize = sizeof(ttb);
+ ttb.dwFlags = TTBBF_VISIBLE | TTBBF_ISSEPARATOR | TTBBF_INTERNAL;
+ ttb.wParamDown = i;
+ TTBAddButton((WPARAM)&ttb, 0);
+}
+
+void LoadAllSeparators()
+{
+ //must be locked
+ int cnt = db_get_b(0, TTB_OPTDIR, "SepCnt", 0);
+ for (int i = 0; i < cnt; i++)
+ InsertSeparator(i);
+}
+
+int SaveAllButtonsOptions()
+{
+ int SeparatorCnt = 0;
+ int LaunchCnt = 0;
+ {
+ mir_cslock lck(csButtonsHook);
+ for (int i = 0; i < Buttons.getCount(); i++)
+ Buttons[i]->SaveSettings(&SeparatorCnt, &LaunchCnt);
+ }
+ db_set_b(0, TTB_OPTDIR, "SepCnt", SeparatorCnt);
+ db_set_b(0, TTB_OPTDIR, "LaunchCnt", LaunchCnt);
+ return 0;
+}
+
+static bool nameexists(const char *name)
+{
+ if (name == NULL)
+ return false;
+
+ for (int i = 0; i < Buttons.getCount(); i++)
+ if ( !lstrcmpA(Buttons[i]->pszName, name))
+ return true;
+
+ return false;
+}
+
+static void Icon2button(TTBButton* but, HANDLE& hIcoLib, HICON& hIcon, bool bIsUp)
+{
+ HANDLE hSrc = bIsUp ? but->hIconHandleUp : but->hIconHandleDn;
+ if (hSrc == NULL) {
+ hIcoLib = NULL, hIcon = NULL;
+ return;
+ }
+
+ hIcoLib = (HANDLE)CallService(MS_SKIN2_ISMANAGEDICON, WPARAM(hSrc), 0);
+ if (!hIcoLib) {
+ char buf[256];
+ mir_snprintf(buf, SIZEOF(buf), "toptoolbar_%s%s", but->name, (bIsUp) ? (but->hIconDn ? "%s_up" : "%s") : "%s_dn");
+ SKINICONDESC sid = {0};
+ sid.cbSize = sizeof(sid);
+ sid.pszSection = "Toolbar";
+ sid.pszName = buf;
+ sid.pszDefaultFile = NULL;
+ sid.pszDescription = but->name;
+ sid.hDefaultIcon = (bIsUp) ? but->hIconUp : but->hIconDn;
+ hIcoLib = Skin_AddIcon(&sid);
+ }
+
+ hIcon = Skin_GetIconByHandle(hIcoLib);
+}
+
+TopButtonInt* CreateButton(TTBButton* but)
+{
+ TopButtonInt* b = new TopButtonInt;
+ b->id = nextButtonId++;
+
+ b->dwFlags = but->dwFlags;
+
+ b->wParamUp = but->wParamUp;
+ b->lParamUp = but->lParamUp;
+ b->wParamDown = but->wParamDown;
+ b->lParamDown = but->lParamDown;
+
+ if ( !(b->dwFlags & TTBBF_ISSEPARATOR)) {
+ b->bPushed = (but->dwFlags & TTBBF_PUSHED) ? TRUE : FALSE;
+
+ if (but->dwFlags & TTBBF_ISLBUTTON) {
+ b->ptszProgram = mir_tstrdup(but->program);
+ b->pszService = mir_strdup(TTB_LAUNCHSERVICE);
+ }
+ else {
+ b->ptszProgram = NULL;
+ b->pszService = mir_strdup(but->pszService);
+ }
+
+ b->pszName = mir_strdup(but->name);
+
+ Icon2button(but, b->hIconHandleUp, b->hIconUp, true);
+ Icon2button(but, b->hIconHandleDn, b->hIconDn, false);
+
+ if (but->cbSize > OLD_TBBUTTON_SIZE) {
+ b->ptszTooltipUp = mir_a2t(but->pszTooltipUp);
+ b->ptszTooltipDn = mir_a2t(but->pszTooltipDn);
+ }
+ }
+ return b;
+}
+
+int ArrangeButtons()
+{
+ mir_cslock lck(csButtonsHook);
+
+ RECT rcClient;
+ GetClientRect(g_ctrl->hWnd, &rcClient);
+ int nBarSize = rcClient.right - rcClient.left;
+ if (nBarSize == 0)
+ return 0;
+
+ int nLineCount = 0;
+ int i, ypos = 1, xpos = g_ctrl->nButtonSpace, nextX = 0, y = 0;
+ int newheight = g_ctrl->nButtonHeight+1, nButtonCount=0;
+
+ for (i=0; i < Buttons.getCount(); i++)
+ if (Buttons[i]->hwnd)
+ nButtonCount++;
+
+ if (nButtonCount == 0)
+ return 0;
+
+ HDWP hdwp = BeginDeferWindowPos(nButtonCount);
+
+ bool bWasButttonBefore;
+ int nUsedWidth, iFirstButtonId = 0, iLastButtonId = 0;
+
+ do
+ {
+ nLineCount++;
+ bWasButttonBefore = false;
+ nUsedWidth = 0;
+
+ for (i=iFirstButtonId; i < Buttons.getCount(); i++) {
+ TopButtonInt *b = Buttons[i];
+ if (b->hwnd == NULL)
+ continue;
+
+ int width = 0;
+ if ( b->isVisible())
+ width = (b->isSep()) ? SEPWIDTH+2 : g_ctrl->nButtonWidth + ((bWasButttonBefore) ? g_ctrl->nButtonSpace : 0);
+ if (nUsedWidth + width > nBarSize)
+ break;
+
+ nUsedWidth += width;
+ iLastButtonId = i+1;
+ bWasButttonBefore = !b->isSep();
+ }
+
+ int nFreeSpace = nBarSize - nUsedWidth;
+
+ for (i=iFirstButtonId; i < iLastButtonId; i++) {
+ TopButtonInt *b = Buttons[i];
+ if (b->hwnd == NULL)
+ continue;
+
+ bool bOldVisible = IsWindowVisible(b->hwnd) != 0;
+ if (bOldVisible != b->isVisible())
+ g_ctrl->bOrderChanged = TRUE;
+
+ if ( b->isVisible()) {
+ hdwp = DeferWindowPos(hdwp, b->hwnd, NULL, nextX, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
+ if ( b->isSep())
+ nextX += SEPWIDTH+2;
+ else
+ nextX += g_ctrl->nButtonWidth + g_ctrl->nButtonSpace;
+ }
+ else hdwp = DeferWindowPos(hdwp, Buttons[i]->hwnd, NULL, nextX, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW);
+ }
+
+ if (iFirstButtonId == iLastButtonId)
+ break;
+
+ iFirstButtonId = iLastButtonId;
+ y += g_ctrl->nButtonHeight + g_ctrl->nButtonSpace;
+ nextX = 0;
+ if (g_ctrl->bSingleLine)
+ break;
+ }
+ while (iFirstButtonId < Buttons.getCount() && y >= 0 && (g_ctrl->bAutoSize || (y + g_ctrl->nButtonHeight <= rcClient.bottom - rcClient.top)));
+
+ if (hdwp)
+ EndDeferWindowPos(hdwp);
+
+ return (g_ctrl->nButtonHeight + g_ctrl->nButtonSpace)*nLineCount - g_ctrl->nButtonSpace;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Toolbar services
+
+// wparam = (TTBButton*)lpTTBButton
+// lparam = hLangpack
+INT_PTR TTBAddButton(WPARAM wParam, LPARAM lParam)
+{
+ if (wParam == 0)
+ return -1;
+
+ TTBButton *but = (TTBButton*)wParam;
+ if (but->cbSize != sizeof(TTBButton) && but->cbSize != OLD_TBBUTTON_SIZE)
+ return -1;
+
+ if ( !(but->dwFlags && TTBBF_ISLBUTTON) && nameexists(but->name))
+ return -1;
+
+ TopButtonInt* b = CreateButton(but);
+ b->hLangpack = (int)lParam;
+ b->LoadSettings();
+ b->CreateWnd();
+ if (b->hwnd == NULL) {
+ delete b;
+ return -1;
+ }
+ {
+ mir_cslock lck(csButtonsHook);
+ Buttons.insert(b);
+ }
+
+ g_ctrl->bOrderChanged = TRUE;
+ ArrangeButtons();
+ AddToOptions(b);
+ return b->id;
+}
+
+// wparam = (HANDLE)hTTButton
+// lparam = 0
+INT_PTR TTBRemoveButton(WPARAM wParam, LPARAM lParam)
+{
+ mir_cslock lck(csButtonsHook);
+
+ int idx;
+ TopButtonInt* b = idtopos(wParam, &idx);
+ if (b == NULL)
+ return -1;
+
+ RemoveFromOptions(b->id);
+
+ Buttons.remove(idx);
+ delete b;
+
+ g_ctrl->bOrderChanged = TRUE;
+ ArrangeButtons();
+ return 0;
+}
+
+// wparam = hTTBButton
+// lparam = state
+INT_PTR TTBSetState(WPARAM wParam, LPARAM lParam)
+{
+ mir_cslock lck(csButtonsHook);
+
+ TopButtonInt* b = idtopos(wParam);
+ if (b == NULL)
+ return -1;
+
+ b->bPushed = (lParam & TTBST_PUSHED)?TRUE:FALSE;
+ b->bPushed = (lParam & TTBST_RELEASED)?FALSE:TRUE;
+ b->SetBitmap();
+ return 0;
+}
+
+// wparam = hTTBButton
+// lparam = 0
+//return = state
+INT_PTR TTBGetState(WPARAM wParam, LPARAM lParam)
+{
+ mir_cslock lck(csButtonsHook);
+ TopButtonInt* b = idtopos(wParam);
+ if (b == NULL)
+ return -1;
+
+ int retval = (b->bPushed == TRUE) ? TTBST_PUSHED : TTBST_RELEASED;
+ return retval;
+}
+
+INT_PTR TTBGetOptions(WPARAM wParam, LPARAM lParam)
+{
+ INT_PTR retval;
+
+ mir_cslock lck(csButtonsHook);
+ TopButtonInt* b = idtopos(wParam);
+ if (b == NULL)
+ return -1;
+
+ switch(LOWORD(wParam)) {
+ case TTBO_FLAGS:
+ retval = b->dwFlags & (~TTBBF_PUSHED);
+ if (b->bPushed)
+ retval |= TTBBF_PUSHED;
+ break;
+
+ case TTBO_TIPNAME:
+ retval = (INT_PTR)b->ptszTooltip;
+ break;
+
+ case TTBO_ALLDATA:
+ if (lParam) {
+ lpTTBButton lpTTB = (lpTTBButton)lParam;
+ if (lpTTB->cbSize != sizeof(TTBButton))
+ break;
+
+ lpTTB->dwFlags = b->dwFlags & (~TTBBF_PUSHED);
+ if (b->bPushed)
+ lpTTB->dwFlags |= TTBBF_PUSHED;
+
+ lpTTB->hIconDn = b->hIconDn;
+ lpTTB->hIconUp = b->hIconUp;
+
+ lpTTB->lParamUp = b->lParamUp;
+ lpTTB->wParamUp = b->wParamUp;
+ lpTTB->lParamDown = b->lParamDown;
+ lpTTB->wParamDown = b->wParamDown;
+
+ if (b->dwFlags & TTBBF_ISLBUTTON)
+ replaceStrT(lpTTB->program, b->ptszProgram);
+ else
+ replaceStr(lpTTB->pszService, b->pszService);
+
+ retval = ( INT_PTR )lpTTB;
+ }
+ break;
+
+ default:
+ retval = -1;
+ break;
+ }
+
+ return retval;
+}
+
+INT_PTR TTBSetOptions(WPARAM wParam, LPARAM lParam)
+{
+ int retval;
+
+ mir_cslock lck(csButtonsHook);
+ TopButtonInt* b = idtopos(HIWORD(wParam));
+ if (b == NULL)
+ return -1;
+
+ switch(LOWORD(wParam)) {
+ case TTBO_FLAGS:
+ if (b->dwFlags == lParam)
+ break;
+
+ retval = b->CheckFlags(lParam);
+
+ if (retval & TTBBF_PUSHED)
+ b->SetBitmap();
+ if (retval & TTBBF_VISIBLE) {
+ ArrangeButtons();
+ b->SaveSettings(0,0);
+ }
+
+ retval = 1;
+ break;
+
+ case TTBO_TIPNAME:
+ if (lParam == 0)
+ break;
+
+ replaceStrT(b->ptszTooltip, TranslateTS( _A2T((LPCSTR)lParam)));
+ SendMessage(b->hwnd,BUTTONADDTOOLTIP,(WPARAM)b->ptszTooltip,BATF_UNICODE);
+ retval = 1;
+ break;
+
+ case TTBO_ALLDATA:
+ if (lParam) {
+ lpTTBButton lpTTB = (lpTTBButton)lParam;
+ if (lpTTB->cbSize != sizeof(TTBButton))
+ break;
+
+ retval = b->CheckFlags(lpTTB->dwFlags);
+
+ int changed = 0;
+ if (b->hIconUp != lpTTB->hIconUp) {
+ b->hIconUp = lpTTB->hIconUp;
+ changed = 1;
+ }
+ if (b->hIconDn != lpTTB->hIconDn) {
+ b->hIconDn = lpTTB->hIconDn;
+ changed = 1;
+ }
+ if (changed)
+ b->SetBitmap();
+
+ if (retval & TTBBF_VISIBLE) {
+ ArrangeButtons();
+ b->SaveSettings(0,0);
+ }
+
+ if (b->dwFlags & TTBBF_ISLBUTTON)
+ replaceStrT(b->ptszProgram, lpTTB->program);
+ else
+ replaceStr(b->pszService, lpTTB->pszService);
+
+ b->lParamUp = lpTTB->lParamUp;
+ b->wParamUp = lpTTB->wParamUp;
+ b->lParamDown = lpTTB->lParamDown;
+ b->wParamDown = lpTTB->wParamDown;
+
+ retval = 1;
+ }
+ break;
+
+ default:
+ retval = -1;
+ break;
+ }
+
+ return retval;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Reload all icons from their icolib handles
+
+int OnIconChange(WPARAM wParam, LPARAM lParam)
+{
+ mir_cslock lck(csButtonsHook);
+ for (int i = 0; i < Buttons.getCount(); i++) {
+ TopButtonInt* b = Buttons[i];
+ if ( !b->hIconHandleUp && !b->hIconHandleDn)
+ continue;
+
+ if (b->hIconHandleUp) {
+ Skin_ReleaseIcon(b->hIconUp);
+ b->hIconUp = Skin_GetIconByHandle(b->hIconHandleUp);
+ }
+ if (b->hIconHandleDn) {
+ Skin_ReleaseIcon(b->hIconDn);
+ b->hIconDn = Skin_GetIconByHandle(b->hIconHandleDn);
+ }
+ DestroyWindow(b->hwnd);
+ b->CreateWnd();
+ }
+
+ if (g_ctrl->hWnd) {
+ g_ctrl->bOrderChanged = true;
+ PostMessage(g_ctrl->hWnd, TTB_UPDATEFRAMEVISIBILITY, TRUE, 0);
+ }
+
+ return 0;
+}
+
+static int OnBGChange(WPARAM wParam, LPARAM lParam)
+{
+ LoadBackgroundOptions();
+ return 0;
+}
+
+static INT_PTR TTBSetCustomProc(WPARAM wParam, LPARAM lParam)
+{
+ g_CustomProc = (pfnCustomProc)wParam;
+ g_CustomProcParam = lParam;
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Adds buttons of plugins being loaded. lParam = HINSTANCE
+
+int OnPluginLoad(WPARAM wParam, LPARAM lParam)
+{
+ CallPluginEventHook((HINSTANCE)lParam, hTTBModuleLoaded, 0, 0);
+ if (g_ctrl->hWnd && g_ctrl->bOrderChanged)
+ PostMessage(g_ctrl->hWnd, TTB_UPDATEFRAMEVISIBILITY, TRUE, 0);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Removes buttons of plugins being unloaded. lParam = HINSTANCE
+
+int OnPluginUnload(WPARAM wParam, LPARAM lParam)
+{
+ int hLangpack = CallService(MS_LANGPACK_LOOKUPHANDLE, 0, lParam);
+ if (hLangpack) {
+ bool bNeedUpdate = false;
+ mir_cslock lck(csButtonsHook);
+
+ for (int i=Buttons.getCount()-1; i >= 0; i--)
+ if (Buttons[i]->hLangpack == hLangpack) {
+ TTBRemoveButton(Buttons[i]->id, 0);
+ bNeedUpdate = true;
+ }
+
+ if (bNeedUpdate) {
+ ArrangeButtons();
+ if (g_ctrl->hWnd)
+ PostMessage(g_ctrl->hWnd, TTB_UPDATEFRAMEVISIBILITY, TRUE, 0);
+ }
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int OnModulesLoad(WPARAM wParam, LPARAM lParam)
+{
+ LoadAllSeparators();
+ LoadAllLButs();
+
+ ArrangeButtons();
+
+ HANDLE hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);//anonymous event
+ if (hEvent != 0)
+ CallService(MS_SYSTEM_WAITONHANDLE, (WPARAM)hEvent, (LPARAM)"TTB_ONSTARTUPFIRE");
+
+ if ( HookEvent(ME_BACKGROUNDCONFIG_CHANGED, OnBGChange)) {
+ char buf[256];
+ sprintf(buf, "TopToolBar Background/%s", TTB_OPTDIR);
+ CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)buf, 0);
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static LRESULT CALLBACK TTBButtonWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = buttonWndProc(hwnd, msg, wParam, lParam);
+
+ if (msg == WM_NCCREATE) {
+ TopButtonInt* p = (TopButtonInt*)((CREATESTRUCT*)lParam)->lpCreateParams;
+ if (g_CustomProc)
+ g_CustomProc((HANDLE)p->id, hwnd, g_CustomProcParam);
+ }
+
+ return lResult;
+}
+
+int LoadToolbarModule()
+{
+ if ( !ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) {
+ if ( !db_get_b(NULL, TTB_OPTDIR, "WarningDone", 0))
+ MessageBox(0, TranslateT("Frames Services not found - plugin disabled.You need MultiWindow plugin."), _T("TopToolBar"), 0);
+ db_set_b(NULL, TTB_OPTDIR, "WarningDone", 1);
+ return 1;
+ }
+
+ g_ctrl = (TTBCtrl*)mir_calloc( sizeof(TTBCtrl));
+ g_ctrl->nButtonHeight = db_get_dw(0, TTB_OPTDIR, "BUTTHEIGHT", DEFBUTTHEIGHT);
+ g_ctrl->nButtonWidth = db_get_dw(0, TTB_OPTDIR, "BUTTWIDTH", DEFBUTTWIDTH);
+ g_ctrl->nButtonSpace = db_get_dw(0, TTB_OPTDIR, "BUTTGAP", DEFBUTTGAP);
+ g_ctrl->nLastHeight = db_get_dw(0, TTB_OPTDIR, "LastHeight", DEFBUTTHEIGHT);
+
+ g_ctrl->bFlatButtons = db_get_b(0, TTB_OPTDIR, "UseFlatButton", true);
+ g_ctrl->bSingleLine = db_get_b(0, TTB_OPTDIR, "SingleLine", false);
+ g_ctrl->bAutoSize = db_get_b(0, TTB_OPTDIR, "AutoSize", true);
+
+ db_unset(NULL, TTB_OPTDIR, "WarningDone");
+
+ InitializeCriticalSection(&csButtonsHook);
+ hBmpSeparator = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SEP));
+
+ HookEvent(ME_SYSTEM_MODULELOAD, OnPluginLoad);
+ HookEvent(ME_SYSTEM_MODULEUNLOAD, OnPluginUnload);
+ HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoad);
+ HookEvent(ME_SKIN2_ICONSCHANGED, OnIconChange);
+ HookEvent(ME_OPT_INITIALISE, TTBOptInit);
+
+ hTTBModuleLoaded = CreateHookableEvent(ME_TTB_MODULELOADED);
+ hTTBInitButtons = CreateHookableEvent(ME_TTB_INITBUTTONS);
+ SetHookDefaultForHookableEvent(hTTBInitButtons, InitInternalButtons);
+
+ CreateServiceFunction("TopToolBar/AddButton", TTBAddButton);
+ CreateServiceFunction(MS_TTB_REMOVEBUTTON, TTBRemoveButton);
+
+ CreateServiceFunction(MS_TTB_SETBUTTONSTATE, TTBSetState);
+ CreateServiceFunction(MS_TTB_GETBUTTONSTATE, TTBGetState);
+
+ CreateServiceFunction(MS_TTB_GETBUTTONOPTIONS, TTBGetOptions);
+ CreateServiceFunction(MS_TTB_SETBUTTONOPTIONS, TTBSetOptions);
+
+ CreateServiceFunction(TTB_LAUNCHSERVICE, LaunchService);
+
+ CreateServiceFunction("TopToolBar/SetCustomProc", TTBSetCustomProc);
+ CreateServiceFunction("TTB_ONSTARTUPFIRE", OnEventFire);
+
+ buttonWndProc = (WNDPROC)CallService("Button/GetWindowProc",0,0);
+ WNDCLASSEX wc = {0};
+ wc.cbSize = sizeof(wc);
+ wc.lpszClassName = TTB_BUTTON_CLASS;
+ wc.lpfnWndProc = TTBButtonWndProc;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.cbWndExtra = sizeof(void*);
+ wc.hbrBackground = 0;
+ wc.style = CS_GLOBALCLASS;
+ RegisterClassEx(&wc);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int UnloadToolbarModule()
+{
+ DestroyHookableEvent(hTTBModuleLoaded);
+ DestroyHookableEvent(hTTBInitButtons);
+
+ DeleteObject(hBmpSeparator);
+ DeleteCriticalSection(&csButtonsHook);
+
+ for (int i=0; i < Buttons.getCount(); i++)
+ delete Buttons[i];
+ Buttons.destroy();
+
+ mir_free(g_ctrl);
+ return 0;
+}