/*
Quick Messages plugin for Miranda IM
Copyright (C) 2008 Danil Mozhar
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 3 of the License, 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, see .
*/
#include "quickmessages.h"
int g_iOPButtonsCount;
BOOL bNeedRestart = FALSE;
BOOL drag = FALSE, bOptionsInit = TRUE;
HTREEITEM hDragItem = NULL;
HWND hButtonsList = NULL;
HWND hMenuTree = NULL;
HWND hwndEdit = NULL;
HWND g_opHdlg = NULL, g_varhelpDlg = NULL;
INT_PTR CALLBACK HelpDlgProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg){
case WM_INITDIALOG:
{
LOGFONT logFont;
HFONT hFont;
RECT rc;
g_varhelpDlg=hdlg;
TranslateDialogDefault(hdlg);
hFont = (HFONT)SendDlgItemMessage(hdlg, IDC_STATICTITLE, WM_GETFONT, 0, 0);
GetObject(hFont, sizeof logFont, &logFont);
logFont.lfWeight = FW_BOLD;
hFont = CreateFontIndirect(&logFont);
SendDlgItemMessage(hdlg, IDC_STATICTITLE, WM_SETFONT, (WPARAM)hFont, 0);
SendDlgItemMessage(hdlg, IDC_STATICTITLE2, WM_SETFONT, (WPARAM)hFont, 0);
SendDlgItemMessage(hdlg, IDC_VARTEXT, WM_SETFONT, (WPARAM)hFont, 0);
SendDlgItemMessage(hdlg, IDC_VARCLIP, WM_SETFONT, (WPARAM)hFont, 0);
SendDlgItemMessage(hdlg, IDC_VARPUNAME, WM_SETFONT, (WPARAM)hFont, 0);
SendDlgItemMessage(hdlg, IDC_VARPLNAME, WM_SETFONT, (WPARAM)hFont, 0);
SendDlgItemMessage(hdlg, IDC_VARCNAME, WM_SETFONT, (WPARAM)hFont, 0);
SendDlgItemMessage(hdlg, IDC_VARCFNAME, WM_SETFONT, (WPARAM)hFont, 0);
SendDlgItemMessage(hdlg, IDC_VARCLNAME, WM_SETFONT, (WPARAM)hFont, 0);
GetWindowRect(g_opHdlg,&rc);
SetWindowPos(hdlg,0,rc.left,rc.top,0,0,SWP_SHOWWINDOW|SWP_NOSIZE);
}
break;
case WM_LBUTTONDOWN:
PostMessage( hdlg,WM_NCLBUTTONDOWN, HTCAPTION,lparam);
break;
case WM_CLOSE:
case WM_DESTROY:
DestroyWindow(g_varhelpDlg);
g_varhelpDlg=NULL;
break;
default:
return FALSE;
}
return TRUE;
}
static LRESULT CALLBACK LabelEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_GETDLGCODE:
return DLGC_WANTALLKEYS;
}
return mir_callNextSubclass(hwnd, LabelEditSubclassProc, msg, wParam, lParam);
}
static LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND hParent = GetParent(hwnd);
switch (msg) {
case WM_GETDLGCODE:
return DLGC_WANTALLKEYS|DLGC_HASSETSEL;
case WM_SETFOCUS:
PostMessage(hwnd,EM_SETSEL,0,-1);
break;
case WM_KEYDOWN:
{
if(wParam==VK_RETURN)
if(hwnd==GetDlgItem(hParent,IDC_BUTTONNAME))
SendMessage(hParent,WM_COMMAND,IDC_BLISTADD,0);
else
SendMessage(hParent,WM_COMMAND,IDC_MTREEADD,0);
}break;
}
return mir_callNextSubclass(hwnd, EditSubclassProc, msg, wParam, lParam);
}
void SetMenuEntryProperties(HWND hdlg)
{
TVITEM tvi;
HTREEITEM hItem=NULL;
ButtonData* bd=NULL;
int pos=0;
if(TreeView_GetCount(hButtonsList)&&(tvi.hItem=TreeView_GetSelection(hButtonsList)))
{
tvi.mask=TVIF_HANDLE|TVIF_PARAM;
TreeView_GetItem(hButtonsList,&tvi);
if (tvi.lParam)
{
ListData* ld = ( ListData* )tvi.lParam;
TCHAR szValue[256];
GetDlgItemText(hdlg, IDC_RCLICKVALUE, szValue, _countof(szValue));
if(mir_tstrlen(szValue))
{
if(ld->ptszOPQValue&&(ld->ptszOPQValue!=ld->ptszQValue))
mir_free(ld->ptszOPQValue);
ld->ptszOPQValue=mir_tstrdup(szValue);
}
ld->bIsOpServName=IsDlgButtonChecked(hdlg,IDC_ISSERVNAME2);
}
}
tvi.hItem=NULL;
if(TreeView_GetCount(hMenuTree)&&(tvi.hItem=TreeView_GetSelection(hMenuTree)))
{
tvi.mask=TVIF_HANDLE|TVIF_PARAM;
TreeView_GetItem(hMenuTree,&tvi);
if (tvi.lParam)
{
ButtonData* bd = ( ButtonData* )tvi.lParam;
TCHAR szValue[256];
GetDlgItemText(hdlg, IDC_MENUVALUE, szValue, _countof(szValue));
if(mir_tstrlen(szValue))
{
if(mir_tstrlen(bd->pszOpValue)&&(bd->pszOpValue!=bd->pszValue))
mir_free(bd->pszOpValue);
bd->pszOpValue=mir_tstrdup(szValue);
}
bd->bOpInQMenu=IsDlgButtonChecked(hdlg,IDC_INQMENU);
bd->bIsOpServName=IsDlgButtonChecked(hdlg,IDC_ISSERVNAME);
}
tvi.mask = TVIF_HANDLE | TVIF_PARAM;
tvi.hItem = TreeView_GetRoot(hMenuTree);
}
while (tvi.hItem) {
TreeView_GetItem(hMenuTree, &tvi);
bd= (ButtonData*)tvi.lParam;
bd->dwOPPos=pos++;
if(hItem=TreeView_GetChild(hMenuTree, tvi.hItem)) {
bd->fEntryOpType&=~QMF_EX_CHILD;
if(bd->pszOpValue){
mir_free(bd->pszOpValue);
bd->pszOpValue=NULL;
}
tvi.hItem=hItem;
continue;
}
else
{
if(bd->fEntryOpType&QMF_EX_SEPARATOR){
if(bd->pszOpValue){
mir_free(bd->pszOpValue);
bd->pszOpValue=NULL;
}}
else
{
if (!bd->pszOpValue)
bd->pszOpValue=mir_tstrdup(LPGENT("Enter Value"));
}
if(TreeView_GetParent(hMenuTree, tvi.hItem))
bd->fEntryOpType|=QMF_EX_CHILD;
else bd->fEntryOpType&=~QMF_EX_CHILD;
if (!(hItem=TreeView_GetNextSibling(hMenuTree, tvi.hItem)))
tvi.hItem=TreeView_GetNextSibling(hMenuTree, TreeView_GetParent(hMenuTree,tvi.hItem));
else
tvi.hItem=hItem;
}
}
}
void SaveMenuTree(HWND hdlg)
{
int iBl=0,i=0,k=0;
int iBtd=g_iButtonsCount;
BOOL bDeleted=FALSE;
char szMEntry[256]={'\0'};
TCHAR strbuf[256];
HTREEITEM hti=NULL;
TVITEM tvi;
g_iButtonsCount=TreeView_GetCount(hButtonsList);
tvi.pszText = strbuf;
tvi.cchTextMax = _countof(strbuf);
tvi.mask=TVIF_HANDLE|TVIF_TEXT ;
tvi.hItem=TreeView_GetRoot(hButtonsList);
TreeView_GetItem(hButtonsList,&tvi);
li_ZeroQuickList(QuickList);
BalanceButtons(iBtd,g_iButtonsCount);
while(ButtonsList[iBl])
{
SortedList * sl=NULL;
ListData* ld=ButtonsList[iBl];
if (!ld->sl) break;
sl=ld->sl;
if(ld->dwOPFlags&QMF_DELETNEEDED)
{
bDeleted=(ld->dwOPFlags&QMF_NEW)?FALSE:TRUE;
if(bDeleted) CleanSettings(ld->dwPos,-1);
DestroyButton(iBl);
continue;
}
if(ld->ptszQValue!=ld->ptszOPQValue)
{
if(ld->ptszQValue)
mir_free(ld->ptszQValue);
ld->ptszQValue=(ld->ptszOPQValue)?ld->ptszOPQValue:NULL;
}
if(ld->ptszButtonName)
mir_free(ld->ptszButtonName);
if(iBl>0)
if(hti=TreeView_GetNextSibling(hButtonsList,hti?hti:tvi.hItem))
{
tvi.hItem=hti;
TreeView_GetItem(hButtonsList,&tvi);
}
ld->ptszButtonName=mir_tstrdup(tvi.pszText);
if(ld->ptszQValue)
{
mir_snprintf(szMEntry, _countof(szMEntry), "ButtonValue_%u", iBl);
db_set_ts(NULL, PLGNAME,szMEntry,ld->ptszQValue);
}
if (ServiceExists(MS_BB_MODIFYBUTTON)&&((ld->dwOPFlags&QMF_NEW)||(ld->dwOPFlags&QMF_RENAMED)||bDeleted))
{
BBButton bb={0};
bb.cbSize=sizeof(BBButton);
bb.pszModuleName=PLGNAME;
bb.dwButtonID=iBl;
bb.ptszTooltip=ld->ptszButtonName;
CallService(MS_BB_MODIFYBUTTON,0,(LPARAM)&bb);
}
mir_snprintf(szMEntry, _countof(szMEntry), "ButtonName_%u", iBl);
db_set_ts(NULL, PLGNAME,szMEntry,ld->ptszButtonName);
ld->dwOPFlags=0;
ld->dwPos=iBl;
ld->bIsServName=ld->bIsOpServName;
mir_snprintf(szMEntry, _countof(szMEntry), "RCEntryIsServiceName_%u", iBl);
db_set_b(NULL, PLGNAME,szMEntry,ld->bIsServName);
bDeleted=FALSE;
qsort(sl->items,sl->realCount,sizeof(ButtonData *),sstSortButtons);
for ( i=0; i < sl->realCount; i++ ) {
ButtonData * bd= (ButtonData *)sl->items[i];
if(bd->dwOPFlags&QMF_DELETNEEDED){
RemoveMenuEntryNode(sl, i--);
continue;
}
bd->bIsServName=bd->bIsOpServName;
bd->bInQMenu=bd->bOpInQMenu;
bd->dwPos=bd->dwOPPos;
bd->fEntryType=bd->fEntryOpType;
bd->dwOPFlags=0;
if(bd->pszName!=bd->pszOpName)
{
if(bd->pszName)
mir_free(bd->pszName);
bd->pszName=bd->pszOpName?bd->pszOpName:NULL;
}
if(bd->pszValue!=bd->pszOpValue)
{
if(bd->pszValue)
mir_free(bd->pszValue);
bd->pszValue=bd->pszOpValue?bd->pszOpValue:NULL;
}
if(bd->bInQMenu)
{
QuickData* qd = (QuickData *)mir_alloc(sizeof(QuickData));
qd->dwPos=k++;
qd->fEntryType=bd->fEntryType;
qd->bIsService=bd->bIsServName;
qd->ptszValue=bd->pszValue;
qd->ptszValueName=bd->pszName;
List_InsertPtr(QuickList,qd);
}
SaveModuleSettings(iBl,bd);
}
CleanSettings(iBl,sl->realCount);
iBl++;
}
db_set_b(NULL, PLGNAME,"ButtonsCount", (BYTE)g_iButtonsCount);
}
void RestoreModuleData(HWND hdlg)
{
int iBl=0,i=0;
char szMEntry[256]={'\0'};
while(ButtonsList[iBl])
{
SortedList * sl=NULL;
ListData* ld=ButtonsList[iBl];
if (!(sl=ld->sl)) break;
if(ld->dwOPFlags&QMF_NEW)
{
DestroyButton(iBl);
continue;
}
if(ld->ptszQValue!=ld->ptszOPQValue)
{
if(ld->ptszOPQValue)
mir_free(ld->ptszOPQValue);
ld->ptszOPQValue=(ld->ptszQValue)?ld->ptszQValue:NULL;
}
ld->bIsOpServName=ld->bIsServName;
ld->dwOPFlags=0;
qsort(sl->items,sl->realCount,sizeof(ButtonData *),sstSortButtons);
for ( i=0; i < sl->realCount; i++ ) {
ButtonData * bd= (ButtonData *)sl->items[i];
if(bd->dwOPFlags&QMF_NEW){
RemoveMenuEntryNode(sl, i--);
continue;
}
bd->bIsOpServName=bd->bIsServName;
bd->bOpInQMenu=bd->bInQMenu;
bd->dwOPPos=bd->dwPos;
bd->fEntryOpType=bd->fEntryType;
bd->dwOPFlags=0;
if(bd->pszName!=bd->pszOpName)
{
if(bd->pszOpName)
mir_free(bd->pszOpName);
bd->pszOpName=bd->pszName?bd->pszName:NULL;
}
if(bd->pszValue!=bd->pszOpValue)
{
if(bd->pszOpValue)
mir_free(bd->pszOpValue);
bd->pszOpValue=bd->pszValue?bd->pszValue:NULL;
}
}
iBl++;
}
}
static int BuildMenuTree(HWND hToolBarTree,SortedList * sl)
{
TVINSERTSTRUCT tvis;
int i;
HTREEITEM hParent=NULL;
tvis.hParent = NULL;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask = TVIF_PARAM | TVIF_TEXT;
TreeView_DeleteAllItems( hToolBarTree );
if (!sl) return 1;
qsort(sl->items,sl->realCount,sizeof(ButtonData *),sstOpSortButtons);
for ( i=0; i < sl->realCount; i++ ) {
ButtonData * bd= (ButtonData *)sl->items[i];
if(bd->dwOPFlags&QMF_DELETNEEDED)
continue;
tvis.item.lParam= (LPARAM) bd;
tvis.item.pszText= bd->pszOpName;
if(bd->fEntryOpType==0)
tvis.hParent = NULL;
hParent=TreeView_InsertItem( hToolBarTree, &tvis );
if(tvis.hParent) TreeView_Expand( hMenuTree, tvis.hParent, TVE_EXPAND );
if (!bd->pszOpValue&&bd->fEntryOpType==0)
{
tvis.hParent = hParent;
}
// else if (!(bd->fEntryOpType&QMF_EX_CHILD))
// tvis.hParent = NULL;
}
return 1;
}
static int BuildButtonsList(HWND hToolBarTree)
{
TVINSERTSTRUCT tvis;
int i=0;
tvis.hParent = NULL;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask =TVIF_PARAM | TVIF_TEXT;
TreeView_DeleteAllItems( hToolBarTree );
//for(i=0;iptszButtonName;
TreeView_InsertItem( hToolBarTree, &tvis );
i++;
}
return 1;
}
///////////////////////////////////
//From UserInfoEx by DeathAxe
//
void MoveItem( HTREEITEM hItem, HTREEITEM hInsertAfter, BOOLEAN bAsChild )
{
TVINSERTSTRUCT tvis;
//TCHAR strbuf[128];
HTREEITEM hParent, hChild, hNewItem;
if ( !hItem || !hInsertAfter )
return;
if ( hItem == hInsertAfter )
return;
switch( ( ULONG_PTR )hInsertAfter ) {
case TVI_ROOT:
case TVI_FIRST:
case TVI_LAST:
hParent = NULL;
bAsChild = FALSE;
break;
default:
hParent = TreeView_GetParent( hMenuTree, hInsertAfter );
break;
}
// do not move a parent next to its own children!
if ( hItem == hParent )
return;
// prepare the insert structure
{
TCHAR strbuf[128];
tvis.item.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT;
tvis.item.pszText=strbuf;
tvis.item.cchTextMax=_countof(strbuf);
tvis.item.hItem=hItem;
TreeView_GetItem(hMenuTree,&tvis.item);
}
// item should be inserted as the first child of an existing root item
if ( bAsChild ) {
tvis.hParent = hInsertAfter;
tvis.hInsertAfter = ( bAsChild == 2 ) ? TVI_LAST : TVI_FIRST ;
}
// item should be inserted after an existing item
else {
tvis.hParent = hParent;
tvis.hInsertAfter = hInsertAfter;
}
// insert the item
if ( !( hNewItem = TreeView_InsertItem( hMenuTree, &tvis )) )
return;
// move children
hInsertAfter = hNewItem;
while( hChild = TreeView_GetChild( hMenuTree, hItem )) {
MoveItem( hChild, hInsertAfter, 2 );
}
// delete old tree
TreeView_DeleteItem( hMenuTree, hItem );
TreeView_SelectItem( hMenuTree, hNewItem );
//TreeView_Expand( hMenuTree, hNewItem, TVE_EXPAND );
}
///////
INT_PTR CALLBACK OptionsProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg){
case WM_INITDIALOG:{
DWORD style;
g_opHdlg=hdlg;
bOptionsInit=TRUE;
TranslateDialogDefault(hdlg);
if(g_iButtonsCount!=db_get_b(NULL, PLGNAME,"ButtonsCount", 0))
{
LOGFONT logFont;
HFONT hFont;
bNeedRestart=TRUE;
EnableWindow(GetDlgItem(hdlg,IDC_BUTTONSLIST),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_BLISTADD),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_BLISTREMOVE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_MENUTREE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_MTREEADD),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_MTREEREMOVE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_MENUVALUE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_RCLICKVALUE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_BUTTONNAME),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_INQMENU),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_MENUNAME),FALSE);
ShowWindow(GetDlgItem(hdlg,IDC_WARNING),SW_SHOW);
hFont = (HFONT)SendDlgItemMessage(hdlg, IDC_WARNING, WM_GETFONT, 0, 0);
GetObject(hFont, sizeof(logFont), &logFont);
logFont.lfWeight = FW_BOLD;
hFont = CreateFontIndirect(&logFont);
SendDlgItemMessage(hdlg, IDC_WARNING, WM_SETFONT, (WPARAM)hFont, 0);
break;
}
g_iOPButtonsCount=g_iButtonsCount;
hButtonsList=GetDlgItem(hdlg,IDC_BUTTONSLIST);
hMenuTree=GetDlgItem(hdlg,IDC_MENUTREE);
style = GetWindowLongPtr(hButtonsList,GWL_STYLE);
style |=TVS_NOHSCROLL;
SetWindowLongPtr(hButtonsList,GWL_STYLE, style);
style = GetWindowLongPtr(hMenuTree,GWL_STYLE);
style |=TVS_NOHSCROLL;
SetWindowLongPtr(hMenuTree,GWL_STYLE, style);
BuildButtonsList(hButtonsList);
if (!TreeView_GetCount(hButtonsList))
EnableWindow(GetDlgItem(hdlg,IDC_RCLICKVALUE),FALSE);
mir_subclassWindow( GetDlgItem(hdlg,IDC_BUTTONNAME), EditSubclassProc);
mir_subclassWindow( GetDlgItem(hdlg,IDC_MENUNAME), EditSubclassProc);
EnableWindow(GetDlgItem(hdlg,IDC_MENUVALUE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_INQMENU),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME),FALSE);
CheckDlgButton(hdlg,IDC_RAUTOSEND,(g_bRClickAuto=db_get_b(NULL,PLGNAME,"RClickAuto",0)) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hdlg,IDC_LAUTOSEND,(g_bLClickAuto=db_get_b(NULL,PLGNAME,"LClickAuto",0)) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hdlg,IDC_ENABLEQUICKMENU,(g_bQuickMenu=db_get_b(NULL, PLGNAME,"QuickMenu", 1)) ? BST_CHECKED : BST_UNCHECKED);
bOptionsInit=FALSE;
}break;
case WM_LBUTTONUP:
if(drag) {
TVHITTESTINFO hti;
HTREEITEM htiAfter=NULL;
ButtonData* bd=NULL;
TVITEM tvi;
RECT rc;
BYTE height;
BOOLEAN bAsChild = FALSE;
TreeView_SetInsertMark(hMenuTree, NULL, 0 );
ReleaseCapture();
SetCursor( LoadCursor( NULL, IDC_ARROW ));
hti.pt.x = ( SHORT )LOWORD( lparam );
hti.pt.y = ( SHORT )HIWORD( lparam );
ClientToScreen(hdlg,&hti.pt);
ScreenToClient(hMenuTree,&hti.pt);
TreeView_HitTest( hMenuTree, &hti );
if(TreeView_GetParent(hMenuTree,hti.hItem)&&TreeView_GetChild(hMenuTree,hDragItem))
break;
if(TreeView_GetChild(hMenuTree,hti.hItem)&&TreeView_GetChild(hMenuTree,hDragItem))
break;
if ( hti.flags & TVHT_ABOVE ) {
htiAfter = TVI_FIRST;
}
else
if ( hti.flags & ( TVHT_NOWHERE|TVHT_BELOW )) {
htiAfter = TVI_LAST;
}
else
if ( hti.flags & ( TVHT_ONITEM|TVHT_ONITEMRIGHT )) {
// check where over the item, the pointer is
if ( !TreeView_GetItemRect( hMenuTree, hti.hItem, &rc, FALSE )) {
drag=0;
break;
}
height = ( BYTE )( rc.bottom - rc.top );
if ( hti.pt.y - ( height / 3 ) < rc.top ) {
HTREEITEM hItem = hti.hItem;
if ( !( hti.hItem = TreeView_GetPrevSibling( hMenuTree, hItem )) ) {
if ( !( hti.hItem = TreeView_GetParent(hMenuTree, hItem )))
htiAfter = TVI_FIRST;
else
bAsChild = TRUE;
}
}
else
if ( hti.pt.y + ( height / 3 ) <= rc.bottom ) {
bAsChild = TRUE;
}
}
if(TreeView_GetChild(hMenuTree,hDragItem)&&bAsChild)
break;
if(hti.hItem){
tvi.hItem=hti.hItem;
tvi.mask=TVIF_PARAM |TVIF_HANDLE;
TreeView_GetItem(hMenuTree,&tvi);
if ((bd=(ButtonData*)tvi.lParam)&&(bd->fEntryOpType&QMF_EX_SEPARATOR))
bAsChild = FALSE;
}
if(TreeView_GetParent(hMenuTree,hti.hItem))
bAsChild = FALSE;
MoveItem( hDragItem, htiAfter?htiAfter:hti.hItem, bAsChild );
SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
drag=0;
}
break;
///////////////////////////////////
//From UserInfoEx by DeathAxe
//
case WM_MOUSEMOVE:
{
if (!drag) break;
{
TVHITTESTINFO hti;
hti.pt.x=(short)LOWORD(lparam);
hti.pt.y=(short)HIWORD(lparam);
ClientToScreen(hdlg,&hti.pt);
ScreenToClient(hMenuTree,&hti.pt);
TreeView_HitTest(hMenuTree,&hti);
if ( hti.flags & ( TVHT_ONITEM|TVHT_ONITEMRIGHT )) {
RECT rc;
BYTE height;
if ( TreeView_GetItemRect(hMenuTree, hti.hItem, &rc, FALSE )) {
height = ( BYTE )( rc.bottom - rc.top );
if ( hti.pt.y - ( height / 3 ) < rc.top ) {
SetCursor( LoadCursor( NULL, IDC_ARROW ));
TreeView_SetInsertMark( hMenuTree, hti.hItem, 0 );
}
else
if ( hti.pt.y + ( height / 3 ) > rc.bottom ) {
SetCursor( LoadCursor( NULL, IDC_ARROW ));
TreeView_SetInsertMark( hMenuTree, hti.hItem, 1 );
}
else {
TreeView_SetInsertMark( hMenuTree, NULL, 0 );
SetCursor( LoadCursor( GetModuleHandle(NULL), MAKEINTRESOURCE( 183 )) );
}
}
}
else {
if ( hti.flags & TVHT_ABOVE ) SendMessage( hMenuTree, WM_VSCROLL, MAKEWPARAM( SB_LINEUP, 0 ), 0 );
if ( hti.flags & TVHT_BELOW ) SendMessage( hMenuTree, WM_VSCROLL, MAKEWPARAM( SB_LINEDOWN, 0 ), 0 );
TreeView_SetInsertMark( hMenuTree, NULL, 0 );
}
}
}break;
/////////////
case WM_DESTROY:
if (g_varhelpDlg)
DestroyWindow(g_varhelpDlg);
g_varhelpDlg=NULL;
break;
case WM_NOTIFY:
switch(((LPNMHDR)lparam)->idFrom) {
case 0:
if (((LPNMHDR)lparam)->code == PSN_APPLY ) {
if (!bNeedRestart){
SetMenuEntryProperties(hdlg);
SaveMenuTree(hdlg);
}
db_set_b(NULL,PLGNAME,"RClickAuto",(BYTE)(g_bRClickAuto=IsDlgButtonChecked(hdlg,IDC_RAUTOSEND)));
db_set_b(NULL,PLGNAME,"LClickAuto",(BYTE)(g_bLClickAuto=IsDlgButtonChecked(hdlg,IDC_LAUTOSEND)));
db_set_b(NULL,PLGNAME,"QuickMenu",(BYTE)(g_bQuickMenu=IsDlgButtonChecked(hdlg,IDC_ENABLEQUICKMENU)));
return 1;
}
else if (((LPNMHDR)lparam)->code == PSN_RESET ) {
if (!bNeedRestart)
RestoreModuleData(hdlg);
return 1;
}
break;
case IDC_MENUTREE:
switch (((LPNMHDR)lparam)->code){
case TVN_KEYDOWN:{
TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*) ((LPNMHDR)lparam);
if ( pTVKeyDown->wVKey == VK_F2 )
TreeView_EditLabel(hMenuTree,TreeView_GetSelection(hMenuTree));
else if ( pTVKeyDown->wVKey == VK_DELETE )
SendMessage(hdlg,WM_COMMAND,IDC_MTREEREMOVE,0);
}break;
case TVN_BEGINLABELEDIT:
hwndEdit=TreeView_GetEditControl(hMenuTree);
mir_subclassWindow(hwndEdit, LabelEditSubclassProc);
break;
case TVN_ENDLABELEDIT:
{
TVITEM tvi;
ButtonData* bd=NULL;
TCHAR strbuf[256];
TCHAR szLabel[256];
tvi.pszText = strbuf;
tvi.cchTextMax = _countof(strbuf);
tvi.mask=TVIF_TEXT |TVIF_HANDLE|TVIF_PARAM;
tvi.hItem=TreeView_GetSelection(hMenuTree);
TreeView_GetItem(hMenuTree,&tvi);
GetWindowText(hwndEdit, szLabel, _countof(szLabel));
hwndEdit=NULL;
if (!mir_tstrlen(szLabel)) break;
if (bd = (ButtonData*)tvi.lParam){
if (!mir_tstrcmp(szLabel,_T("---"))) {
if(TreeView_GetChild(hMenuTree,tvi.hItem))
break;
else{
bd->fEntryOpType=QMF_EX_SEPARATOR;
EnableWindow(GetDlgItem(hdlg,IDC_MENUVALUE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME),FALSE);
SetDlgItemText(hdlg, IDC_MENUVALUE, _T(""));
}
}
else {
bd->fEntryOpType&=~QMF_EX_SEPARATOR;
EnableWindow(GetDlgItem(hdlg,IDC_MENUVALUE),TRUE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME),TRUE);
SetDlgItemText(hdlg, IDC_MENUVALUE, bd->pszOpValue/*?bd->pszOpValue:bd->pszValue*/);
}
bd->pszOpName=mir_tstrdup(szLabel);
tvi.pszText=szLabel;
TreeView_SetItem(hMenuTree, &tvi);
SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
}
}
break;
case NM_KILLFOCUS:
TreeView_EndEditLabelNow(hButtonsList, 1);
break;
case TVN_BEGINDRAG:
SetCapture(hdlg);
drag=1;
hDragItem=((LPNMTREEVIEW)lparam)->itemNew.hItem;
TreeView_SelectItem(hMenuTree,hDragItem);
break;
case TVN_SELCHANGING:
{
HTREEITEM hti = TreeView_GetSelection(hMenuTree);
if (hti==NULL)
break;
TVITEM tvi;
tvi.hItem=hti;
tvi.mask=TVIF_HANDLE|TVIF_PARAM;
TreeView_GetItem(hMenuTree,&tvi);
if (tvi.lParam == 0)
break;
ButtonData *bd = ( ButtonData* )tvi.lParam;
if (bd) {
TCHAR szValue[256];
GetDlgItemText(hdlg, IDC_MENUVALUE, szValue, _countof(szValue));
if(mir_tstrlen(szValue))
{
if(bd->pszOpValue&&(bd->pszOpValue!=bd->pszValue))
mir_free(bd->pszOpValue);
bd->pszOpValue=mir_tstrdup(szValue);
}
bd->bOpInQMenu=IsDlgButtonChecked(hdlg,IDC_INQMENU);
bd->bIsOpServName=IsDlgButtonChecked(hdlg,IDC_ISSERVNAME);
}
}
break;
case TVN_SELCHANGED:
{
HTREEITEM hti = TreeView_GetSelection(hMenuTree);
if (hti == NULL)
break;
TVITEM tvi;
tvi.mask=TVIF_HANDLE|TVIF_PARAM;
tvi.hItem=hti;
TreeView_GetItem(hMenuTree,&tvi);
ButtonData *bd = ( ButtonData* )tvi.lParam;
if (bd) {
if (!TreeView_GetChild(hMenuTree, tvi.hItem)&&!(bd->fEntryOpType&QMF_EX_SEPARATOR))
{
EnableWindow(GetDlgItem(hdlg,IDC_MENUVALUE),TRUE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME),TRUE);
EnableWindow(GetDlgItem(hdlg,IDC_INQMENU),TRUE);
SetDlgItemText(hdlg, IDC_MENUVALUE, bd->pszOpValue/*?bd->pszOpValue:bd->pszValue*/);
}
else
{
EnableWindow(GetDlgItem(hdlg,IDC_MENUVALUE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME),FALSE);
if (!(bd->fEntryOpType&QMF_EX_SEPARATOR))
EnableWindow(GetDlgItem(hdlg,IDC_INQMENU),FALSE);
SetDlgItemText(hdlg, IDC_MENUVALUE, _T(""));
}
CheckDlgButton(hdlg,IDC_INQMENU,bd->bOpInQMenu ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hdlg,IDC_ISSERVNAME,bd->bIsOpServName ? BST_CHECKED : BST_UNCHECKED);
}
}
}
break;
case IDC_BUTTONSLIST:
switch (((LPNMHDR)lparam)->code) {
case TVN_KEYDOWN:{
TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*) ((LPNMHDR)lparam);
if ( pTVKeyDown->wVKey == VK_F2 )
TreeView_EditLabel(hButtonsList,TreeView_GetSelection(hButtonsList));
else if ( pTVKeyDown->wVKey == VK_DELETE )
SendMessage(hdlg,WM_COMMAND,IDC_BLISTREMOVE,0);
}break;
case TVN_BEGINLABELEDIT:
hwndEdit = TreeView_GetEditControl(hButtonsList);
mir_subclassWindow(hwndEdit, LabelEditSubclassProc);
break;
case TVN_ENDLABELEDIT:
{
TVITEM tvi;
TCHAR strbuf[128];
TCHAR szLabel[128];
tvi.pszText = strbuf;
tvi.cchTextMax = _countof(strbuf);
tvi.mask=TVIF_TEXT |TVIF_HANDLE|TVIF_PARAM;
tvi.hItem=TreeView_GetSelection(hButtonsList);
TreeView_GetItem(hButtonsList,&tvi);
GetWindowText(hwndEdit, szLabel, _countof(szLabel));
hwndEdit=NULL;
if (!mir_tstrlen(szLabel)) break;
tvi.pszText=szLabel;
((ListData*)tvi.lParam)->dwOPFlags|=QMF_RENAMED;
TreeView_SetItem(hButtonsList, &tvi);
SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
}
break;
case TVN_SELCHANGING:
SetMenuEntryProperties(hdlg);
break;
case TVN_SELCHANGED:
{
HTREEITEM hti = TreeView_GetSelection(hButtonsList);
if(hti==NULL||!TreeView_GetCount(hButtonsList)) {
EnableWindow(GetDlgItem(hdlg,IDC_MENUVALUE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_INQMENU),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME2),FALSE);
SetDlgItemText(hdlg, IDC_MENUVALUE, _T(""));
break;
}
TVITEM tvi;
tvi.mask=TVIF_HANDLE|TVIF_PARAM;
tvi.hItem=hti;
TreeView_GetItem(hButtonsList,&tvi);
if(tvi.lParam==0) break;
BuildMenuTree(hMenuTree,(SortedList *)((ListData*)tvi.lParam)->sl);
SetDlgItemText(hdlg, IDC_MENUVALUE, _T(""));
EnableWindow(GetDlgItem(hdlg,IDC_RCLICKVALUE),TRUE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME2),TRUE);
CheckDlgButton(hdlg,IDC_ISSERVNAME2,((ListData*)tvi.lParam)->bIsOpServName ? BST_CHECKED : BST_UNCHECKED);
if (((ListData*)tvi.lParam)->ptszOPQValue)
SetDlgItemText(hdlg, IDC_RCLICKVALUE, ((ListData*)tvi.lParam)->ptszOPQValue);
else
SetDlgItemText(hdlg, IDC_RCLICKVALUE, _T(""));
}
break;
}
break;
}
break;
case WM_COMMAND:
switch(LOWORD(wparam)) {
case IDC_VARHELP:
if (!g_varhelpDlg)
g_varhelpDlg=CreateDialog(hinstance,MAKEINTRESOURCE(IDD_HELPDIALOG), 0, HelpDlgProc);
else
//ShowWindow(g_varhelpDlg,SW_SHOWDEFAULT);
SetWindowPos(g_varhelpDlg,0,0,0,0,0,SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE);
break;
case IDC_BLISTADD:
{
TVINSERTSTRUCT tvis;
ListData* ld=NULL;
TCHAR namebuff[MAX_PATH]={'\0'};
int count=TreeView_GetCount(hButtonsList);
if (count>10) break;
if(g_iOPButtonsCount==99){
MessageBox(NULL, TranslateT("Congratulation!\r\nYou have clicked this button 100 times!\r\nThere was access violation at this point...\r\nAnd now function for freeing resources must be called...\r\nBut no! there's only break :D"), TranslateT("You win!"),MB_OK);
break;
}
ld = (ListData *)mir_alloc(sizeof(ListData));
ButtonsList[g_iOPButtonsCount++]=ld;
ld->sl=List_Create(0,1);
ld->dwOPFlags=QMF_NEW;
ld->bIsOpServName=0;
ld->ptszButtonName=NULL;
ld->ptszOPQValue=NULL;
ld->ptszQValue=NULL;
tvis.hParent = NULL;
tvis.hInsertAfter = TVI_LAST;
GetDlgItemText(hdlg, IDC_BUTTONNAME, namebuff, _countof(namebuff));
tvis.item.mask=TVIF_PARAM|TVIF_TEXT;
tvis.item.pszText=(mir_tstrlen(namebuff))?namebuff:TranslateT("New Button");
tvis.item.lParam=(LPARAM)ld;
TreeView_SelectItem(hButtonsList,TreeView_InsertItem(hButtonsList,&tvis));
}break;
case IDC_BLISTREMOVE:
{
TVITEM tvi;
ListData* ld;
if (!(tvi.hItem=TreeView_GetSelection(hButtonsList)))
break;
tvi.mask=TVIF_HANDLE|TVIF_PARAM;
TreeView_GetItem(hButtonsList,&tvi);
ld= (ListData*)tvi.lParam;
ld->dwOPFlags|=QMF_DELETNEEDED;
TreeView_DeleteItem(hButtonsList,tvi.hItem);
if (!TreeView_GetCount(hButtonsList)) {
TreeView_DeleteAllItems(hMenuTree);
EnableWindow(GetDlgItem(hdlg,IDC_MENUVALUE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_RCLICKVALUE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_INQMENU),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME2),FALSE);
SetDlgItemText(hdlg, IDC_MENUVALUE, _T(""));
SetDlgItemText(hdlg, IDC_RCLICKVALUE, _T(""));
}
}break;
case IDC_MTREEADD:
{
TVINSERTSTRUCT tvis;
TVITEM tvi;
ButtonData *bd=NULL;
SortedList *sl=NULL;
TCHAR namebuff[MAX_PATH]={'\0'};
if (!TreeView_GetCount(hButtonsList)) break;
if (!(tvi.hItem=TreeView_GetSelection(hButtonsList))) break;
bd = (ButtonData *)mir_alloc(sizeof(ButtonData));
memset(bd,0,sizeof(ButtonData));
GetDlgItemText(hdlg, IDC_MENUNAME, namebuff, _countof(namebuff));
bd->dwOPPos=TreeView_GetCount(hMenuTree)-1;
bd->pszOpName=mir_tstrlen(namebuff)?mir_tstrdup(namebuff):mir_tstrdup(TranslateT("New Menu Entry"));
bd->pszOpValue=mir_tstrdup(bd->pszOpName);
bd->fEntryOpType=!mir_tstrcmp(namebuff,_T("---"))?QMF_EX_SEPARATOR:0;
bd->dwOPFlags=QMF_NEW;
bd->pszName=NULL;
bd->pszValue=NULL;
tvi.mask=TVIF_HANDLE|TVIF_PARAM;
TreeView_GetItem(hButtonsList,&tvi);
sl=((ListData*)tvi.lParam)->sl;
List_InsertPtr(sl,bd);
tvis.hParent = NULL;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask=TVIF_PARAM|TVIF_TEXT;
tvis.item.pszText=bd->pszOpName;
tvis.item.lParam=(LPARAM)bd;
TreeView_SelectItem(hMenuTree,TreeView_InsertItem(hMenuTree,&tvis));
}break;
case IDC_MTREEREMOVE:
{
TVITEM tvi;
TVINSERTSTRUCT tvis;
HTREEITEM hti=NULL;
ButtonData *bd=NULL;
tvi.mask=TVIF_HANDLE|TVIF_PARAM;
if (!(tvi.hItem=TreeView_GetSelection(hMenuTree)))
break;
TreeView_GetItem(hMenuTree,&tvi);
hti=tvi.hItem;
bd= (ButtonData*)tvi.lParam;
bd->dwOPFlags|=QMF_DELETNEEDED;
if(tvi.hItem=TreeView_GetChild(hMenuTree,tvi.hItem)) {
TCHAR strbuf[128];
while(tvi.hItem){
tvis.hInsertAfter=hti;
tvi.pszText = strbuf;
tvi.cchTextMax = _countof(strbuf);
tvi.mask=TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT;
TreeView_GetItem(hMenuTree,&tvi);
tvis.hParent=NULL;
tvis.item=tvi;
TreeView_InsertItem(hMenuTree,&tvis);
tvi.hItem=TreeView_GetNextSibling(hMenuTree,tvi.hItem);
}
}
TreeView_DeleteItem(hMenuTree,hti);
if (!TreeView_GetCount(hMenuTree)) {
EnableWindow(GetDlgItem(hdlg,IDC_MENUVALUE),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_ISSERVNAME),FALSE);
EnableWindow(GetDlgItem(hdlg,IDC_INQMENU),FALSE);
SetDlgItemText(hdlg, IDC_MENUVALUE, _T(""));
}
}break;
}
break;
case WM_CLOSE:
EndDialog(hdlg,0);
return 0;
}
if (HIWORD(wparam)==BN_CLICKED && GetFocus()==(HWND)lparam)
SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
else if ((HIWORD(wparam) == EN_CHANGE)&&(GetFocus()==(HWND)lparam))
if (!bOptionsInit) SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
return 0;
}
int OptionsInit(WPARAM wparam,LPARAM lparam)
{
OPTIONSDIALOGPAGE odp = { 0 };
odp.position = 940000000;
odp.hInstance = hinstance;
odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
odp.pszTitle = LPGEN("Quick Messages");
odp.pfnDlgProc = OptionsProc;
odp.pszGroup = LPGEN("Message sessions");
odp.flags = ODPF_BOLDGROUPS;
Options_AddPage(wparam,&odp);
return 0;
}