static void CustomizeTocInfoTip(LPNMTVGETINFOTIP nmit)
{
    PageDestination *link = ((DocTocItem *)nmit->lParam)->GetLink();
    ScopedMem<WCHAR> path(link ? link->GetDestValue() : nullptr);
    if (!path)
        return;
    CrashIf(!link); // /analyze claims that this could happen - it really can't
    CrashIf(link->GetDestType() != Dest_LaunchURL && link->GetDestType() != Dest_LaunchFile && link->GetDestType() != Dest_LaunchEmbedded);

    str::Str<WCHAR> infotip;

    RECT rcLine, rcLabel;
    HWND hTV = nmit->hdr.hwndFrom;
    // Display the item's full label, if it's overlong
    TreeView_GetItemRect(hTV, nmit->hItem, &rcLine, FALSE);
    TreeView_GetItemRect(hTV, nmit->hItem, &rcLabel, TRUE);
    if (rcLine.right + 2 < rcLabel.right) {
        WCHAR buf[INFOTIPSIZE+1] = { 0 };  // +1 just in case
        TVITEM item;
        item.hItem = nmit->hItem;
        item.mask = TVIF_TEXT;
        item.pszText = buf;
        item.cchTextMax = INFOTIPSIZE;
        TreeView_GetItem(hTV, &item);
        infotip.Append(item.pszText);
        infotip.Append(L"\r\n");
    }

    if (Dest_LaunchEmbedded == link->GetDestType())
        path.Set(str::Format(_TR("Attachment: %s"), path.Get()));

    infotip.Append(path);
    str::BufSet(nmit->pszText, nmit->cchTextMax, infotip.Get());
}
Example #2
0
void CMsgTree::SetDefMsg(int iMode, int ID)
{
	for (int i = 0; i < _countof(SettingsList); i++) {
		if (SettingsList[i].Status == iMode) {
			if (MsgTreePage.GetValue(SettingsList[i].DBSetting) != ID) {
				RECT rc;
				COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl();
				int OrderOld = TreeCtrl->IDToOrder(MsgTreePage.GetValue(SettingsList[i].DBSetting));
				if (OrderOld >= 0 && TreeView_GetItemRect(hTreeView, TreeCtrl->Value[OrderOld].hItem, &rc, false))
					InvalidateRect(hTreeView, &rc, true); // refresh icons of previous default tree item

				int OrderNew = TreeCtrl->IDToOrder(ID);
				if (OrderNew >= 0 && TreeView_GetItemRect(hTreeView, TreeCtrl->Value[OrderNew].hItem, &rc, false))
					InvalidateRect(hTreeView, &rc, true); // refresh new default item icons

				MsgTreePage.SetValue(SettingsList[i].DBSetting, ID);
				NMMSGTREE nm = { 0 };
				if (OrderOld >= 0)
					nm.ItemOld = &TreeCtrl->Value[OrderOld];
				if (OrderNew >= 0)
					nm.ItemNew = &TreeCtrl->Value[OrderNew];
				nm.hdr.code = MTN_DEFMSGCHANGED;
				nm.hdr.hwndFrom = hTreeView;
				nm.hdr.idFrom = GetDlgCtrlID(hTreeView);
				SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm);
			}
			break;
		}
	}
}
Example #3
0
VOID TreeListUpdateTooltips(
    HWND hwndTreeList
)
{
    HWND TreeControl = (HWND)GetWindowLongPtr(hwndTreeList, TL_TREECONTROL_SLOT),
        ToolTips = (HWND)GetWindowLongPtr(hwndTreeList, TL_TOOLTIPS_SLOT),
        Header = (HWND)GetWindowLongPtr(hwndTreeList, TL_HEADERCONTROL_SLOT);

    PTL_SUBITEMS subitems;

    HTREEITEM   item = TreeView_GetRoot(TreeControl);
    RECT        rc, subrc;
    TOOLINFO    tool;
    ULONG       i = 0, c;
    LONG        cx;
    TVITEMEX    itemex;

    RtlSecureZeroMemory(&rc, sizeof(rc));
    Header_GetItemRect(Header, 0, &rc);
    cx = rc.right;

    c = (ULONG)SendMessage(ToolTips, TTM_GETTOOLCOUNT, 0, 0);
    RtlSecureZeroMemory(&tool, sizeof(tool));
    tool.cbSize = sizeof(tool);

    while (SendMessage(ToolTips, TTM_ENUMTOOLS, i, (LPARAM)&tool) && (i < c)) {
        if (!TreeView_GetItemRect(TreeControl, (HTREEITEM)(tool.uId - tool.lParam), &rc, FALSE)) {
            SendMessage(ToolTips, TTM_DELTOOL, 0, (LPARAM)&tool);
            continue;
        }
        i++;
    }

    while (item) {
        if (TreeView_GetItemRect(TreeControl, item, &rc, TRUE)) {
            RtlSecureZeroMemory(&itemex, sizeof(itemex));
            itemex.hItem = item;
            itemex.mask = TVIF_HANDLE | TVIF_PARAM;
            TreeView_GetItem(TreeControl, &itemex);

            if (rc.right > cx)
                rc.right = cx;
            AddTooltipItemSub(TreeControl, ToolTips, (UINT_PTR)item, 0, &rc);

            if (itemex.lParam) {
                subitems = (PTL_SUBITEMS)itemex.lParam;
                for (i = 0; i < subitems->Count; i++) {
                    if (!Header_GetItemRect(Header, i + 1, &subrc))
                        break;
                    subrc.top = rc.top;
                    subrc.bottom = rc.bottom;
                    AddTooltipItemSub(TreeControl, ToolTips, i + 1 + (UINT_PTR)item, i + 1, &subrc);
                }
            }

        }
        item = TreeView_GetNextVisible(TreeControl, item);
    }
}
Example #4
0
static VOID
OnContext(PMAIN_WND_INFO Info,
          LPARAM lParam)
{
    HTREEITEM hSelected;
    POINT pt;
    RECT rc;

    INT xPos = GET_X_LPARAM(lParam);
    INT yPos = GET_Y_LPARAM(lParam);

    hSelected = TreeView_GetSelection(Info->hTreeView);

    if (TreeView_GetItemRect(Info->hTreeView,
                         hSelected,
                         &rc,
                         TRUE))
    {
        if (GetCursorPos(&pt) &&
            ScreenToClient(Info->hTreeView, &pt) &&
            PtInRect(&rc, pt))
        {
            TrackPopupMenuEx(Info->hShortcutMenu,
                             TPM_RIGHTBUTTON,
                             xPos,
                             yPos,
                             Info->hMainWnd,
                             NULL);
        }
    }
}
Example #5
0
static BOOL
ViewDlg_ToggleCheckItem(HWND hwndDlg, HTREEITEM hItem)
{
    HWND hwndTreeView = GetDlgItem(hwndDlg, IDC_VIEW_TREEVIEW);

    // get the item
    TV_ITEM Item;
    INT i;
    ZeroMemory(&Item, sizeof(Item));
    Item.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_PARAM;
    Item.hItem = hItem;
    if (!TreeView_GetItem(hwndTreeView, &Item))
        return FALSE;       // no such item

    VIEWTREE_ENTRY *pEntry = ViewTree_GetItem(Item.lParam);
    if (pEntry == NULL)
        return FALSE;       // no such item
    if (pEntry->bGrayed)
        return FALSE;       // disabled

    // toggle check mark
    Item.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
    switch (pEntry->dwType)
    {
        case AETYPE_CHECKBOX:
            pEntry->bChecked = !pEntry->bChecked;
            break;

        case AETYPE_RADIO:
            // reset all the entries of the same parent
            for (i = 0; i < s_ViewTreeEntryCount; ++i)
            {
                VIEWTREE_ENTRY *pEntry2 = &s_ViewTreeEntries[i];
                if (pEntry->dwParentID == pEntry2->dwParentID)
                {
                    pEntry2->bChecked = FALSE;

                    Item.hItem = pEntry2->hItem;
                    INT iImage = ViewTree_GetImage(pEntry2);
                    Item.iImage = Item.iSelectedImage = iImage;
                    TreeView_SetItem(hwndTreeView, &Item);
                }
            }
            pEntry->bChecked = TRUE;
            break;

        default:
            return FALSE;   // failure
    }
    Item.iImage = Item.iSelectedImage = ViewTree_GetImage(pEntry);
    Item.hItem = hItem;
    TreeView_SetItem(hwndTreeView, &Item);

    // redraw the item
    RECT rcItem;
    TreeView_GetItemRect(hwndTreeView, hItem, &rcItem, FALSE);
    InvalidateRect(hwndTreeView, &rcItem, TRUE);
    return TRUE;    // success
}
Example #6
0
void CCList::SetExtraImage(HTREEITEM hItem, int iColumn, int iImage) // set iImage to CLC_EXTRAICON_EMPTY to reset image
{
	_ASSERT(iColumn < MAXEXTRAICONS);
	GetItemData(hItem).ExtraIcons[iColumn] = iImage;
	RECT rc;
	if (TreeView_GetItemRect(hTreeView, hItem, &rc, false))
		InvalidateRect(hTreeView, &rc, true);
}
Example #7
0
LRESULT
TreeListOnCustomDraw(
	__in PTREELIST_OBJECT Object,
	__in LPNMHDR lp
	)
{
	LRESULT Status;
	LPNMTVCUSTOMDRAW lpcd = (LPNMTVCUSTOMDRAW)lp;

	Status = CDRF_DODEFAULT;

	switch (lpcd->nmcd.dwDrawStage) {

		case CDDS_PREPAINT:

			//SetViewportOrgEx(lpcd->nmcd.hdc, Object->ScrollOffset, 0, NULL);
			Status = CDRF_NOTIFYITEMDRAW;
			break;

		case CDDS_ITEMPREPAINT:
			
            //
            // Track item information for custom drawing after post painting stage
            //

			lpcd->clrText = Object->clrText;
			lpcd->clrTextBk = Object->clrBack;

			Object->ItemFocus = FALSE;
			if(lpcd->nmcd.uItemState & CDIS_FOCUS) {
				Object->ItemFocus = TRUE;
			}

			TreeView_GetItemRect(Object->hWndTree, (HTREEITEM)lpcd->nmcd.dwItemSpec, 
				                 &Object->ItemRect, TRUE);

			Object->ItemRect.right = min(lpcd->nmcd.rc.right, Object->HeaderWidth);
			Status = CDRF_NOTIFYPOSTPAINT;
			break;

		case CDDS_ITEMPOSTPAINT:

			TreeListDrawItem(Object, lpcd->nmcd.hdc, 
                             (HTREEITEM)lpcd->nmcd.dwItemSpec, 
                             lpcd->nmcd.lItemlParam);

            Status = CDRF_SKIPDEFAULT; 
			break;
	}

	return Status;
}
Example #8
0
/**
 * name:	ShowItem
 * class:	CPsTree
 * desc:	displays on of the items in the treeview
 * param:	iPageIndex	- the index of the treeitem in the array.
 *			needWidth	- gives and takes the width, the treeview must have to show all items properly
 * return:	TRUE if item was added successfully, FALSE otherwise
 **/
HTREEITEM CPsTree::ShowItem(const int iPageIndex, LPWORD needWidth)
{
	TVINSERTSTRUCT tvii;
	CPsTreeItem *pti;

	// check parameters
	if (!_hWndTree || 
		!IsIndexValid(iPageIndex) || 
		!(pti = _pItems[iPageIndex]) ||
		!pti->Name() ||
		!pti->Label())
	{
		MsgErr(GetParent(_hWndTree), LPGENT("Due to a parameter error, one of the treeitems can't be added!"));
		return NULL;
	}	
	// item is visible at the moment
	if ((tvii.itemex.hItem = pti->Hti()) == NULL)
	{
		RECT rc;
		const int iParent = pti->Parent();
		
		// init the rest of the treeitem
		tvii.hParent = IsIndexValid(iParent) ? ShowItem(iParent, needWidth) : NULL;
		tvii.hInsertAfter		= (_dwFlags & PSTVF_SORTTREE) ? TVI_SORT : TVI_LAST;
		tvii.itemex.mask		= TVIF_TEXT|TVIF_PARAM|TVIF_STATE;
		tvii.itemex.pszText		= pti->Label();
		tvii.itemex.state		= pti->State() == DBTVIS_EXPANDED ? TVIS_EXPANDED : 0;
		tvii.itemex.stateMask	= TVIS_EXPANDED;
		tvii.itemex.lParam		= iPageIndex;
		// set images
		if ((tvii.itemex.iImage = tvii.itemex.iSelectedImage = pti->Image()) != -1)
		{
			tvii.itemex.mask |= TVIF_IMAGE|TVIF_SELECTEDIMAGE;
		}
		// insert item into tree if set visible
		if ((tvii.itemex.hItem = TreeView_InsertItem(_hWndTree, &tvii)) == NULL) 
		{
			MsgErr(GetParent(_hWndTree), LPGENT("A fatal error occurred on adding a property sheet page!\nDialog creation aborted!"));
			return NULL;
		}
		pti->Hti(tvii.itemex.hItem);
		// calculate width of treeview
		if (needWidth && TreeView_GetItemRect(_hWndTree, pti->Hti(), &rc, TRUE) && rc.right > *needWidth)
		{
			*needWidth = (WORD)rc.right;
		}
	}
	return tvii.itemex.hItem;
}
Example #9
0
VOID TreeListAutoExpand(
    HWND hwndHeader,
    LPNMTREEVIEW nhdr
)
{
    RECT        irc;
    LONG        cx = 0, xleft = 0;
    HDITEM      hdi;
    HTREEITEM   citem = TreeView_GetChild(nhdr->hdr.hwndFrom, nhdr->itemNew.hItem);

    RtlSecureZeroMemory(&irc, sizeof(irc));
    TreeView_GetItemRect(nhdr->hdr.hwndFrom, citem, &irc, TRUE);
    xleft = irc.left;

    while (citem) {
        RtlSecureZeroMemory(&irc, sizeof(irc));
        TreeView_GetItemRect(nhdr->hdr.hwndFrom, citem, &irc, TRUE);

        if (irc.left < xleft)
            break;

        if (irc.right > cx)
            cx = irc.right;

        citem = TreeView_GetNextVisible(nhdr->hdr.hwndFrom, citem);
    }

    RtlSecureZeroMemory(&hdi, sizeof(hdi));
    hdi.mask = HDI_WIDTH;
    Header_GetItem(hwndHeader, 0, &hdi);

    if (hdi.cxy < cx + 8)
        hdi.cxy = cx + 8;

    Header_SetItem(hwndHeader, 0, &hdi);
}
Example #10
0
    bool GetNodeRect(_Ty Key, PRECT pRc) {

        bool r          = false;
        HTREEITEM hItem = KeyToHandle(Key);

        if (NULL != hItem) {

            if (TRUE == TreeView_GetItemRect(m_hWnd, hItem, pRc, FALSE)) {

                r = true;

            }

        }

        return r;
    }
Example #11
0
/**
 * name:	OnIconsChanged
 * class:	CPsTreeItem
 * desc:	Handles reloading icons if changed by icolib
 * params:	none
 * return:	nothing
 **/
void CPsTreeItem::OnIconsChanged(CPsTree *pTree)
{
	HICON hIcon;
	RECT rc;

	// update tree item icons
	if (pTree->ImageList() && (hIcon = IcoLib_GetIcon(IconKey())) != NULL) {
		_iImage = (_iImage > 0)
			? ImageList_ReplaceIcon(pTree->ImageList(), _iImage, hIcon)
			: ImageList_AddIcon(pTree->ImageList(), hIcon);
		
		if (_hItem && TreeView_GetItemRect(pTree->Window(), _hItem, &rc, 0))
			InvalidateRect(pTree->Window(), &rc, TRUE);
	}
	// update pages icons
	OnPageIconsChanged();
}
Example #12
0
LRESULT
CDeviceView::OnContextMenu(
    _In_ LPARAM lParam
    )
{
    HTREEITEM hSelected = TreeView_GetSelection(m_hTreeView);

    RECT rc;
    if (TreeView_GetItemRect(m_hTreeView,
                             hSelected,
                             &rc,
                             TRUE))
    {
        POINT pt;
        if (GetCursorPos(&pt) &&
            ScreenToClient(m_hTreeView, &pt) &&
            PtInRect(&rc, pt))
        {
            CNode *Node = GetSelectedNode();
            if (Node)
            {
                // Create the context menu
                HMENU hContextMenu = CreatePopupMenu();

                // Add the actions for this node
                BuildActionMenuForNode(hContextMenu, Node, false);

                INT xPos = GET_X_LPARAM(lParam);
                INT yPos = GET_Y_LPARAM(lParam);

                // Display the menu
                TrackPopupMenuEx(hContextMenu,
                                 TPM_RIGHTBUTTON,
                                 xPos,
                                 yPos,
                                 m_hMainWnd,
                                 NULL);

                DestroyMenu(hContextMenu);
            }
        }
    }

    return 0;
}
Example #13
0
HTREEITEM CCList::HitTest(LPPOINT pt, PDWORD hitFlags) // pt is relative to control; returns hItem or NULL
{
	TVHITTESTINFO hti;
	hti.pt = *pt;
	TreeView_HitTest(hTreeView, &hti);
	*hitFlags = 0;
	if (hti.flags & TVHT_ABOVE)
		*hitFlags |= MCLCHT_ABOVE;

	if (hti.flags & TVHT_BELOW)
		*hitFlags |= MCLCHT_BELOW;

	if (hti.flags & TVHT_TOLEFT)
		*hitFlags |= MCLCHT_TOLEFT;

	if (hti.flags & TVHT_TORIGHT)
		*hitFlags |= MCLCHT_TORIGHT;

	if (hti.flags & TVHT_NOWHERE)
		*hitFlags |= MCLCHT_NOWHERE;

	if (hti.flags & TVHT_ONITEMINDENT)
		*hitFlags |= MCLCHT_ONITEMINDENT;

	if (hti.flags & (TVHT_ONITEMICON | TVHT_ONITEMSTATEICON))
		*hitFlags |= MCLCHT_ONITEMICON;

	if (hti.flags & TVHT_ONITEMLABEL)
		*hitFlags |= MCLCHT_ONITEMLABEL;

	if (hti.flags & TVHT_ONITEMRIGHT)
		*hitFlags |= MCLCHT_ONITEMRIGHT;

	if (hti.flags & (TVHT_ONITEMINDENT | TVHT_ONITEM | TVHT_ONITEMRIGHT)) {
		// extraicon tests
		RECT rc;
		if (TreeView_GetItemRect(hTreeView, hti.hItem, &rc, false)) {
			int nIndex = (rc.right - pt->x - 1) / EXTRAICON_XSTEP;
			if (nIndex >= 0 && nIndex < MAXEXTRAICONS && GetItemData(hti.hItem).ExtraIcons[nIndex] != CLC_EXTRAICON_EMPTY)
				*hitFlags |= MCLCHT_ONITEMEXTRA | (nIndex << 24);
		}
	}
	return hti.hItem;
}
Example #14
0
//---------------------------------------------------//
// TreeView_StartProc
//---------------------------------------------------//
BOOL TreeView_StartProc(HWND hWndActive)
{	GetmHpVarStruct()->hWndCurCtrl=NULL;
	/*if(*GetmHpVarStruct()->CourantTask->GetmHpCtrlName()!=0)
	{	if(mHpPak_IsDotNetHwnd(hWndActive))
		{   int iState=0,iStyle=0;
			GetmHpVarStruct()->hWndCurCtrl=mHpPak_GetDotNetCtrlHandle(hWndActive,GetmHpVarStruct()->CourantTask->GetmHpCtrlName(),iStyle,iState);
		}
	}*/
    if(!GetmHpVarStruct()->hWndCurCtrl)
        GetmHpVarStruct()->hWndCurCtrl=GetCtrlWnd(hWndActive,GetmHpVarStruct()->CourantTask->GetmHpCtrlID());
	if(!IsCtrlReady(hWndActive,GetmHpVarStruct()->hWndCurCtrl)) return FALSE;
	RECT CtrlRct;
	GetWindowRect(GetmHpVarStruct()->hWndCurCtrl,&CtrlRct);
	GetmHpVarStruct()->SelItemListe->EmptyGroupListe();
	GetTVitemSelList(GetmHpVarStruct()->hWndCurCtrl,TreeView_GetRoot(GetmHpVarStruct()->hWndCurCtrl),0);
	GetmHpVarStruct()->SelItemListe->ReplaceCurrent();
	hCurSelItm=GetNexthTreeItemToSel(GetmHpVarStruct()->hWndCurCtrl,TreeView_GetRoot(GetmHpVarStruct()->hWndCurCtrl));
	if(hCurSelItm==NULL)
	{	bFindItm=FALSE;
		GetmHpVarStruct()->CourantTask->SetmHpStep(13);
		GetmHpVarStruct()->YnextPos=(int)(((CtrlRct.bottom-CtrlRct.top)/2)+CtrlRct.top);
		GetmHpVarStruct()->XnextPos=(int)(((CtrlRct.right-CtrlRct.left)/2)+CtrlRct.left);
	}
	else
	{	bFindItm=TRUE;
		if(GetmHpVarStruct()->imHpMode==1) TreeView_EnsureVisible(GetmHpVarStruct()->hWndCurCtrl,hCurSelItm);
	    RECT itmRct;
		TreeView_GetItemRect(GetmHpVarStruct()->hWndCurCtrl,hCurSelItm,&itmRct,TRUE);
		ListTreeStatusPos(hWndActive,itmRct);
		if(!GetmHpVarStruct()->AscensSens)
		{	GetmHpVarStruct()->YnextPos=(int)(CtrlRct.top+((itmRct.bottom-itmRct.top)/2)+itmRct.top);
			GetmHpVarStruct()->XnextPos=(int)(CtrlRct.left+((itmRct.right-itmRct.left)/2)+itmRct.left);
			// Click | DoubleClick
			if(!GetmHpVarStruct()->SelItemListe->IsNextIndexExist()) GetmHpVarStruct()->CourantTask->SetmHpStep(10);
		}
		else // Not visible
		{	GetmHpVarStruct()->CourantTask->SetmHpStep(10);
			MoveOnScrollBar(GetmHpVarStruct()->hWndCurCtrl,CtrlRct);
		}
	}
	return TRUE;
}
Example #15
0
/**
 * name:	BeginLabelEdit
 * class:	CPsTree
 * desc:	begins the labeledit mode
 * param:	hItem		- handle of the treeitm whose label to edit
 * return:	0
 **/
int CPsTree::BeginLabelEdit(HTREEITEM hItem)
{
	CPsTreeItem* pti;

	// tree is readonly
	if (db_get_b(NULL, MODNAME, SET_PROPSHEET_READONLYLABEL, 0))
		return 0;

	// get item text
	if (!hItem && !(hItem = TreeView_GetSelection(_hWndTree)))
		return 0;
	if (pti = FindItemByHandle(hItem))
		{
		RECT rc, rcTree;

		// create the edit control
		GetClientRect(_hWndTree, &rcTree);
		TreeView_GetItemRect(_hWndTree, hItem, &rc, TRUE);
		_hLabelEdit = CreateWindowEx(WS_EX_NOPARENTNOTIFY|WS_EX_CLIENTEDGE,
						_T( "EDIT" ),
						pti->Label(),
						WS_VISIBLE|ES_AUTOHSCROLL|WS_CHILD,
						rc.left, rc.top,
						rcTree.right - rc.left, rc.bottom - rc.top,
						_hWndTree,
						NULL,
						ghInst,
						NULL );
		if (_hLabelEdit)
		{
			_hDragItem = hItem;
			SetUserData(_hLabelEdit, this);
			mir_subclassWindow(_hLabelEdit, TPropsheetTree_LabelEditProc);
			SendMessage(_hLabelEdit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0 );
			Edit_SetSel(_hLabelEdit, 0, -1);
			Edit_LimitText(_hLabelEdit, MAX_TINAME);
			SetFocus(_hLabelEdit);
			return 0;
		}
	}
	return 1;
}
Example #16
0
VOID
TreeListGetTreeRectMostRight(
	__in PTREELIST_OBJECT Object,
	__out PLONG MostRight
	)
{
	HTREEITEM hTreeItem;
	HWND hWndTree;
	RECT Rect;

	hWndTree = Object->hWndTree;
	hTreeItem = TreeView_GetFirstVisible(hWndTree);
	*MostRight = 0;

	while (hTreeItem != NULL) {
		TreeView_GetItemRect(hWndTree, hTreeItem, &Rect, TRUE);
		*MostRight = max(Rect.right, *MostRight);
		hTreeItem = TreeView_GetNextVisible(hWndTree, hTreeItem);
	}
}
Example #17
0
/*
static DrawTheImage(HIMAGELIST himl)
{
	HDC hDC;
	hDC=GetDC(NULL);
	ImageList_Draw(himl,0,hDC,0,0,ILD_NORMAL);
	ImageList_Draw(himl,1,hDC,20,0,ILD_NORMAL);
	ReleaseDC(NULL,hDC);
}
*/
static void Main_OnBeginDrag(HWND hwndTV, LPNMTREEVIEW lpnmtv) 
{ 
    HIMAGELIST himl;    // handle to image list 
    RECT rcItem;        // bounding rectangle of item 

    // Tell the tree view control to create an image to use 
    // for dragging. 
	hDragWnd=hwndTV;
    himl = TreeView_CreateDragImage(hwndTV, lpnmtv->itemNew.hItem);  // Real OK
	hDragItem=lpnmtv->itemNew.hItem;

    // Get the bounding rectangle of the item being dragged. 
    TreeView_GetItemRect(hwndTV, lpnmtv->itemNew.hItem, &rcItem, TRUE); 
  
    // Get the heading level and the amount that the child items are 
    // indented. 
    //dwLevel = 1;//lpnmtv->itemNew.lParam; 
    //dwIndent = (DWORD) SendMessage(hwndTV, TVM_GETINDENT, 0, 0); 
 
    //ImageList_SetDragCursorImage(himl,0,0,0);
	// Start the drag operation. 

    //ShowCursor(FALSE); 
	ImageList_BeginDrag(himl, 0, 0,0);

	//    ImageList_DragEnter(NULL,0,0);
    ImageList_DragEnter(hDragWnd,0,0);
    //ImageList_DragShowNolock(TRUE);
    // Hide the mouse cursor, and direct mouse input to the 
    // parent window. 
	//DrawTheImage(himl);

    SetCapture(GetParent(hwndTV)); 
    fDragging = TRUE; 
    return; 
} 
Example #18
0
static void OnFavTreeContextMenu(WindowInfo* win, PointI pt) {
    TVITEM item;
    if (pt.x != -1 || pt.y != -1) {
        TVHITTESTINFO ht = {0};
        ht.pt.x = pt.x;
        ht.pt.y = pt.y;

        MapWindowPoints(HWND_DESKTOP, win->hwndFavTree, &ht.pt, 1);
        TreeView_HitTest(win->hwndFavTree, &ht);
        if ((ht.flags & TVHT_ONITEM) == 0)
            return; // only display menu if over a node in tree

        TreeView_SelectItem(win->hwndFavTree, ht.hItem);
        item.hItem = ht.hItem;
    } else {
        item.hItem = TreeView_GetSelection(win->hwndFavTree);
        if (!item.hItem) {
            return;
        }
        RECT rcItem;
        if (TreeView_GetItemRect(win->hwndFavTree, item.hItem, &rcItem, TRUE)) {
            MapWindowPoints(win->hwndFavTree, HWND_DESKTOP, (POINT*)&rcItem, 2);
            pt.x = rcItem.left;
            pt.y = rcItem.bottom;
        } else {
            WindowRect rc(win->hwndFavTree);
            pt = rc.TL();
        }
    }

    item.mask = TVIF_PARAM;
    TreeView_GetItem(win->hwndFavTree, &item);
    Favorite* toDelete = (Favorite*)item.lParam;

    HMENU popup = BuildMenuFromMenuDef(menuDefFavContext, dimof(menuDefFavContext), CreatePopupMenu());

    INT cmd = TrackPopupMenu(popup, TPM_RETURNCMD | TPM_RIGHTBUTTON, pt.x, pt.y, 0, win->hwndFavTree, nullptr);
    DestroyMenu(popup);
    if (IDM_FAV_DEL == cmd) {
        RememberFavTreeExpansionStateForAllWindows();
        if (toDelete) {
            DisplayState* f = gFavorites.GetByFavorite(toDelete);
            gFavorites.Remove(f->filePath, toDelete->pageNo);
        } else {
            // toDelete == nullptr => this is a parent node signifying all bookmarks in a file
            item.hItem = TreeView_GetChild(win->hwndFavTree, item.hItem);
            item.mask = TVIF_PARAM;
            TreeView_GetItem(win->hwndFavTree, &item);
            toDelete = (Favorite*)item.lParam;
            DisplayState* f = gFavorites.GetByFavorite(toDelete);
            gFavorites.RemoveAllForFile(f->filePath);
        }
        UpdateFavoritesTreeForAllWindows();
        prefs::Save();

        // TODO: it would be nice to have a system for undo-ing things, like in Gmail,
        // so that we can do destructive operations without asking for permission via
        // invasive model dialog boxes but also allow reverting them if were done
        // by mistake
    }
}
Example #19
0
static void TreeCtrlOnPaint(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC 		hDC;
	RECT		rcClip, rcClient;
	HDC 		memDC;
	HBITMAP 	bitmap;
	HBITMAP 	hOldBitmap;

	HBITMAP hBackground = GetBackgroundBitmap();
	MYBITMAPINFO *bmDesc = GetBackgroundInfo();

	hDC = BeginPaint(hWnd, &ps);

	GetClipBox(hDC, &rcClip);
	GetClientRect(hWnd, &rcClient);
	
	// Create a compatible memory DC
	memDC = CreateCompatibleDC(hDC);

	// Select a compatible bitmap into the memory DC
	bitmap = CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left,
									rcClient.bottom - rcClient.top);
	hOldBitmap = SelectObject(memDC, bitmap);
	
	// First let the control do its default drawing.
	CallWindowProc(g_lpTreeWndProc, hWnd, uMsg, (WPARAM)memDC, 0);

	// Draw bitmap in the background
	{
		HPALETTE hPAL;		 
		HDC maskDC;
		HBITMAP maskBitmap;
		HDC tempDC;
		HDC imageDC;
		HBITMAP bmpImage;
		HBITMAP hOldBmpImage;
		HBITMAP hOldMaskBitmap;
		HBITMAP hOldHBitmap;
		int i, j;
		RECT rcRoot;

		// Now create a mask
		maskDC = CreateCompatibleDC(hDC);	
		
		// Create monochrome bitmap for the mask
		maskBitmap = CreateBitmap(rcClient.right - rcClient.left,
								  rcClient.bottom - rcClient.top, 
								  1, 1, NULL);

		hOldMaskBitmap = SelectObject(maskDC, maskBitmap);
		SetBkColor(memDC, GetSysColor(COLOR_WINDOW));

		// Create the mask from the memory DC
		BitBlt(maskDC, 0, 0, rcClient.right - rcClient.left,
			   rcClient.bottom - rcClient.top, memDC, 
			   rcClient.left, rcClient.top, SRCCOPY);

		tempDC = CreateCompatibleDC(hDC);
		hOldHBitmap = SelectObject(tempDC, hBackground);

		imageDC = CreateCompatibleDC(hDC);
		bmpImage = CreateCompatibleBitmap(hDC,
										  rcClient.right - rcClient.left, 
										  rcClient.bottom - rcClient.top);
		hOldBmpImage = SelectObject(imageDC, bmpImage);

		hPAL = GetBackgroundPalette();
		if (hPAL == NULL)
			hPAL = CreateHalftonePalette(hDC);

		if (GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE && hPAL != NULL)
		{
			SelectPalette(hDC, hPAL, FALSE);
			RealizePalette(hDC);
			SelectPalette(imageDC, hPAL, FALSE);
		}
		
		// Get x and y offset
		TreeView_GetItemRect(hWnd, TreeView_GetRoot(hWnd), &rcRoot, FALSE);
		rcRoot.left = -GetScrollPos(hWnd, SB_HORZ);

		// Draw bitmap in tiled manner to imageDC
		for (i = rcRoot.left; i < rcClient.right; i += bmDesc->bmWidth)
			for (j = rcRoot.top; j < rcClient.bottom; j += bmDesc->bmHeight)
				BitBlt(imageDC,  i, j, bmDesc->bmWidth, bmDesc->bmHeight, 
					   tempDC, 0, 0, SRCCOPY);

		// Set the background in memDC to black. Using SRCPAINT with black and any other
		// color results in the other color, thus making black the transparent color
		SetBkColor(memDC, RGB(0,0,0));
		SetTextColor(memDC, RGB(255,255,255));
		BitBlt(memDC, rcClip.left, rcClip.top, rcClip.right - rcClip.left,
			   rcClip.bottom - rcClip.top,
			   maskDC, rcClip.left, rcClip.top, SRCAND);

		// Set the foreground to black. See comment above.
		SetBkColor(imageDC, RGB(255,255,255));
		SetTextColor(imageDC, RGB(0,0,0));
		BitBlt(imageDC, rcClip.left, rcClip.top, rcClip.right - rcClip.left, 
			   rcClip.bottom - rcClip.top,
			   maskDC, rcClip.left, rcClip.top, SRCAND);

		// Combine the foreground with the background
		BitBlt(imageDC, rcClip.left, rcClip.top, rcClip.right - rcClip.left,
			   rcClip.bottom - rcClip.top, 
			   memDC, rcClip.left, rcClip.top, SRCPAINT);

		// Draw the final image to the screen
		BitBlt(hDC, rcClip.left, rcClip.top, rcClip.right - rcClip.left,
			   rcClip.bottom - rcClip.top, 
			   imageDC, rcClip.left, rcClip.top, SRCCOPY);
		
		SelectObject(maskDC, hOldMaskBitmap);
		SelectObject(tempDC, hOldHBitmap);
		SelectObject(imageDC, hOldBmpImage);

		DeleteDC(maskDC);
		DeleteDC(imageDC);
		DeleteDC(tempDC);
		DeleteObject(bmpImage);
		DeleteObject(maskBitmap);

		if (GetBackgroundPalette() == NULL)
		{
			DeleteObject(hPAL);
			hPAL = 0;
		}
	}

	SelectObject(memDC, hOldBitmap);
	DeleteObject(bitmap);
	DeleteDC(memDC);
	EndPaint(hWnd, &ps);
	ReleaseDC(hWnd, hDC);
}
Example #20
0
LRESULT CALLBACK WndProc(
      HWND hWnd,         // window handle
      UINT message,      // type of message
      WPARAM uParam,     // additional information
      LPARAM lParam      // additional information
      )
{
   FARPROC lpProcAbout;  // pointer to the "About" function
   int wmId, wmEvent;

//****************** NEW CODE START *********

#define ptrNMHDR       ((LPNMHDR)lParam)
#define ptrNM_TREEVIEW ((NM_TREEVIEW *)lParam)
#define ptrTV_DISPINFO ((TV_DISPINFO *)lParam)

          RECT       rcItem;
   static HIMAGELIST hDragImage;
   static BOOL       bDragging;
   static HTREEITEM  hDragItem;

   switch (message) {

      case WM_NOTIFY: // This is a new Chicago message for control
                      // notifications

         switch (ptrNMHDR->code)
           {
           case TVN_BEGINDRAG: // Sent by TreeView when user
                               // wants to drag an item.

             // Only allow drag & drop for the actual coaster
             // items. The "itemNew" field of the NM_TREEVIEW
             // structure contains the attribytes of the item
             // we are going to drag. Therefore, since we are
             // using the lParam field to store an ITEM_TYPE_*
             // value, we check that field.

             if ( ITEM_TYPE_COASTER_NAME == ptrNM_TREEVIEW->itemNew.lParam)
               {
               // The hDragImage variable is declared static,
               // so the code in WM_LBUTTONUP can delete it when
               // the user stops dragging. Here we create a
               // drag image to use for the ImageList_StartDrag
               // API.

               hDragImage = TreeView_CreateDragImage
                              (
                              ptrNMHDR->hwndFrom,
                              ptrNM_TREEVIEW->itemNew.hItem
                              );

               // Get the location of the item rectangle's text.

               TreeView_GetItemRect
                 (
                 ptrNMHDR->hwndFrom,            // Handle of TreeView
                 ptrNM_TREEVIEW->itemNew.hItem, // Item in TreeView
                 &rcItem,                       // RECT to store result
                 TRUE                           // Rect of label text only
                 );

               // Cache away the handle of the item to drag into a
               // staticly declared variable, so the code in
               // WM_LBUTTONUP can know what the user is dragging.

               hDragItem = ptrNM_TREEVIEW->itemNew.hItem;

               // Start the drag ala ImageList

               ImageList_BeginDrag(hDragImage, 0,
                 ptrNM_TREEVIEW->ptDrag.x - rcItem.left, // Offset hotspot
                 ptrNM_TREEVIEW->ptDrag.y - rcItem.top);


               ImageList_DragEnter(ptrNMHDR->hwndFrom,
                 ptrNM_TREEVIEW->ptDrag.x,  // Coords of image to drag
                 ptrNM_TREEVIEW->ptDrag.y);

               // Capture the mousey to this window

               ShowCursor ( FALSE );
               SetCapture ( hWnd );

               // Set a staticly declared drag flag so the WM_MOUSEMOVE
               // and WM_LBUTTONUP messages know to take action.

               bDragging = TRUE;
               }

             return 0L;  // Return value is irrelevant

           case TVN_GETDISPINFO: // Sent by TreeView just before it paints
                                 // an item declared with callback values.

             // Our "state" items have the I_IMAGECALLBACK value
             // used for the iImage and iSelectedImage fields. This
             // TVN_GETDISPINFO code will be called whenever the
             // item is about to be drawn. It is out responsibility
             // to add code to fill in the images. The code below
             // uses a different image depending on if the item is
             // expanded or collapsed. That attribute is in the
             // state field of the item passed in the TV_DISPINFO
             // structure.

             // Our lParam is where we store what state the item
             // represents. Therefore, we will switch on that so
             // we can indicate the correct image to use.

             if ( ptrTV_DISPINFO->item.state & TVIS_EXPANDED )
               {
               switch (ptrTV_DISPINFO->item.lParam)
                 {
                 case ITEM_TYPE_STATE_CA:

                   ptrTV_DISPINFO->item.iImage =
                   ptrTV_DISPINFO->item.iSelectedImage = iImageCA_OPEN;
                   break;

                 case ITEM_TYPE_STATE_NY:

                   ptrTV_DISPINFO->item.iImage =
                   ptrTV_DISPINFO->item.iSelectedImage = iImageNY_OPEN;
                   break;

                 case ITEM_TYPE_STATE_OH:

                   ptrTV_DISPINFO->item.iImage =
                   ptrTV_DISPINFO->item.iSelectedImage = iImageOH_OPEN;
                   break;
                 }
               }
             else  // Collapsed item
               {
               switch (ptrTV_DISPINFO->item.lParam)
                 {
                 case ITEM_TYPE_STATE_CA:

                   ptrTV_DISPINFO->item.iImage =
                   ptrTV_DISPINFO->item.iSelectedImage = iImageCA;
                   break;

                 case ITEM_TYPE_STATE_NY:

                   ptrTV_DISPINFO->item.iImage =
                   ptrTV_DISPINFO->item.iSelectedImage = iImageNY;
                   break;

                 case ITEM_TYPE_STATE_OH:

                   ptrTV_DISPINFO->item.iImage =
                   ptrTV_DISPINFO->item.iSelectedImage = iImageOH;
                   break;
                 }
               }
             return TRUE;

           case TVN_BEGINLABELEDIT: // Sent by TreeView when user single
                                    // clicks on an item in a TreeView
                                    // that has the TVS_EDITLABELS style
                                    // bit set.

             // Only allow label editing for the coaster names

             if (ITEM_TYPE_COASTER_NAME == ptrTV_DISPINFO->item.lParam)
               return 0;  // Return 0 to OK edit
             else
               return 1;  // Return non-zero to disallow edit
             break;

           case TVN_ENDLABELEDIT:   // Sent by TreeView when user presses
                                    // the ENTER key or ESC key, to end
                                    // an in-place edit session. If the user
                                    // pressed the ESC key, the pszText
                                    // field of the item in the TV_DISPINFO
                                    // field is NULL.

             // if user pressed ENTER to accept edits


             if ( ptrTV_DISPINFO->item.pszText)
               {
               // Set the "change mask" to indicate that the only attribute
               // we wish to change is the text field. The TV_DISPINFO
               // structure has already been filled out with the new
               // text the user typed in, we just need to pass that on
               // to the TreeView control. This is our chance to evaluate
               // the contents of this field and change it.


               ptrTV_DISPINFO->item.mask = TVIF_TEXT;

               TreeView_SetItem
                 (
                   ptrNMHDR->hwndFrom,      // Handle of TreeView
                   &(ptrTV_DISPINFO->item)  // TV_ITEM structure w/changes
                 );
               }
             break;

           }

         return (DefWindowProc(hWnd, message, uParam, lParam));

      case WM_MOUSEMOVE: // Since the mouse capture is set to this
                         // window while we do our drag & drop,
                         // we check for the drag flag and process
                         // the WM_MOUSEMOVE message.

         if (bDragging)
           {
           HTREEITEM       hTarget;  // Item under mouse
           TV_HITTESTINFO  tvht;     // Used for hit testing

           // Do standard drag drop movement

           ImageList_DragMove ( LOWORD (lParam), HIWORD (lParam));

           // Fill out hit test struct with mouse pos

           tvht.pt.x = LOWORD (lParam);
           tvht.pt.y = HIWORD (lParam);

           // Check to see if an item lives under the mouse

           if ( hTarget = TreeView_HitTest
                            (
                            hWndTreeView,  // This is the global variable
                            &tvht          // TV_HITTESTINFO struct
                            )
              )
             {
             TV_ITEM         tvi;           // Temporary Item

             tvi.mask       = TVIF_PARAM; // We want to fetch the
                                          // lParam field.

             tvi.hItem      = hTarget;    // Set the handle of the
                                          // item to fetch.

             TreeView_GetItem ( hWndTreeView, &tvi ); // Fetch, spot!

             // Check to see if the lParam is a valid item to drop
             // onto (in this case, another roller coaster, such as
             // the Coney Island Cyclone). Skip this operation if
             // the item is already selected (to avoid flicker)

             if ( ITEM_TYPE_COASTER_NAME == tvi.lParam )
               {
               if ( hTarget != TreeView_GetDropHilight (hWndTreeView))
                 {
                 // Hide the drag image
                 ImageList_DragShowNolock ( FALSE );  //DragShow to DragShowNoLock lithangw
                 // Select the item
                 TreeView_SelectDropTarget ( hWndTreeView, hTarget );
                 // Show the drag image
                 ImageList_DragShowNolock ( TRUE ); //DragShow to DragShowNoLock lithangw
                 }
               return 0L;
               }
             }

           // If we made it here, then the user has either
           // dragged the mouse over an invalid item, or no item.
           // Hide any current drop target, this is a no-no drop
           ImageList_DragShowNolock ( FALSE );  //screen update problem tokuroy
           TreeView_SelectDropTarget ( hWndTreeView, NULL );
           ImageList_DragShowNolock ( TRUE );   //screen update problem tokuroy
           }
         break;

      case WM_LBUTTONUP: // Since the mouse capture is set to this
                         // window while we do our drag & drop,
                         // we check for the drag flag and process
                         // the WM_LBUTTONUP message.


         if (bDragging)
           {
           HTREEITEM       hTarget;       // Item under mouse
           TV_ITEM         tvi;           // Temporary Item
           TV_INSERTSTRUCT tvIns;         // Insert struct
           char            szBuffer[256]; // Item text buffer

           // End the drag
           ImageList_EndDrag();
           // Bring back the cursor
           ShowCursor ( TRUE );
           // Release the mouse capture
           ReleaseCapture();
           // Clear the drag flag
           bDragging = FALSE;
           // Clean up the image list object
           ImageList_Destroy ( hDragImage );
           hDragImage = NULL;

           // First, check to see if there is a valid drop point.
           // The cheezy way to do this is to check for a highlighted
           // drop target, since the logic to validate drop points
           // is in the WM_MOUSEMOVE. Duping that code here would
           // be a headache.

           if ( hTarget = TreeView_GetDropHilight (hWndTreeView))
             {
             // If we made it here, then we need to move the item.
             // First, we will fetch it, specifying the attributes
             // we need to copy.

             tvi.mask       = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
             tvi.hItem      = hDragItem;
             tvi.pszText    = szBuffer;
             tvi.cchTextMax = sizeof(szBuffer);

             TreeView_GetItem ( hWndTreeView, &tvi );

             // Now, figure the new place to put it by filling out
             // the TV_INSERTSTRUCT structure, to use the drop target
             // as the sibling to insert after, and using the drop
             // target's parent as the parent to insert this one
             // after as well.

             tvIns.hParent         = TreeView_GetParent ( hWndTreeView, hTarget );
             tvIns.hInsertAfter    = hTarget;
             tvIns.item            = tvi;

             // Delete the old item

             TreeView_DeleteItem ( hWndTreeView, hDragItem );

             // And add the new item (if your app tracks the handles of
             // the items, you want to use the return value
             // of this function to update your data structure that
             // tracks the handles.

             TreeView_InsertItem ( hWndTreeView, &tvIns );
             }

           // Clear any drop highlights on the TreeView

           TreeView_SelectDropTarget ( hWndTreeView, NULL );
           }
         break;

      case WM_SIZE:

         if ( hWndTreeView )     // Standard code to keep the TreeView
                                 // sized up with the main window
           {
           SetWindowPos ( hWndTreeView,
                          NULL,
                          0, 0,
                          LOWORD (lParam),
                          HIWORD (lParam),
                          SWP_NOZORDER
                        );
           }
         break;

//****************** NEW CODE END *********

      case WM_COMMAND:  // message: command from application menu

         // Message packing of uParam and lParam have changed for Win32,
         // let us handle the differences in a conditional compilation:
         #if defined (_WIN32)
             wmId    = LOWORD(uParam);
			    wmEvent = HIWORD(uParam);
         #else
            wmId    = uParam;
            wmEvent = HIWORD(lParam);
         #endif

         switch (wmId) {
            case IDM_ABOUT:
               lpProcAbout = MakeProcInstance((FARPROC)About, hInst);

               DialogBox(hInst,           // current instance
                  "AboutBox",             // dlg resource to use
                  hWnd,                   // parent handle
                  (DLGPROC)lpProcAbout);  // About() instance address

               FreeProcInstance(lpProcAbout);
               break;

            case IDM_EXIT:
               DestroyWindow (hWnd);
               break;

            case IDM_HELPCONTENTS:
               if (!WinHelp (hWnd, "TREEVIEW.HLP", HELP_KEY,(DWORD)(LPSTR)"CONTENTS")) {
                  MessageBox (GetFocus(),
                     "Unable to activate help",
                     szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);
				
               }
               break;

            case IDM_HELPSEARCH:
               if (!WinHelp(hWnd, "TREEVIEW.HLP", HELP_PARTIALKEY, (DWORD)(LPSTR)"")) {
                  MessageBox (GetFocus(),
                     "Unable to activate help",
                     szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);
               }
               break;

            case IDM_HELPHELP:
               if(!WinHelp(hWnd, (LPSTR)NULL, HELP_HELPONHELP, 0)) {
                  MessageBox (GetFocus(),
                     "Unable to activate help",
                     szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);
               }
               break;

            // Here are all the other possible menu options,
            // all of these are currently disabled:
            case IDM_NEW:
            case IDM_OPEN:
            case IDM_SAVE:
            case IDM_SAVEAS:
            case IDM_UNDO:
            case IDM_CUT:
            case IDM_COPY:
            case IDM_PASTE:
            case IDM_LINK:
            case IDM_LINKS:

            default:
               return (DefWindowProc(hWnd, message, uParam, lParam));
         }
         break;

      case WM_DESTROY:  // message: window being destroyed

         PostQuitMessage(0);
         break;

      default:          // Passes it on if unproccessed
         return (DefWindowProc(hWnd, message, uParam, lParam));
   }
   return (0);
}
Example #21
0
LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	CCList *dat = CWndUserData(hWnd).GetCList();
	switch (Msg) {
	case WM_NOTIFY:
		{
			LPNMHDR pnmh = (LPNMHDR)lParam;
			if (pnmh->hwndFrom == dat->hTreeView) {
				switch (pnmh->code) {
				case TVN_ITEMEXPANDED: // just set an appropriate group image
					{
						LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam;
						TVITEM tvItem;
						tvItem.hItem = pnmtv->itemNew.hItem;
						tvItem.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
						tvItem.iImage = tvItem.iSelectedImage = (pnmtv->itemNew.state & TVIS_EXPANDED) ? IMAGE_GROUPOPEN : IMAGE_GROUPSHUT;
						TreeView_SetItem(dat->hTreeView, &tvItem);
					}
					break;
				case TVN_SELCHANGED:
					{
						LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam;
						TREEITEMARRAY OldSelection = dat->SelectedItems;
						for (int i = 0; i < dat->SelectedItems.GetSize(); i++) {
							if (dat->SelectedItems[i] != pnmtv->itemNew.hItem) {
								TreeView_SetItemState(dat->hTreeView, dat->SelectedItems[i], 0, TVIS_SELECTED);
							}
						}
						dat->SelectedItems.RemoveAll();
						if (pnmtv->itemNew.hItem) {
							dat->SelectedItems.AddElem(pnmtv->itemNew.hItem);
							dat->SelectGroups(pnmtv->itemNew.hItem, true);
						}
						NMCLIST nm;
						nm.hdr.code = MCLN_SELCHANGED;
						nm.hdr.hwndFrom = dat->hTreeView;
						nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView);
						nm.OldSelection = &OldSelection;
						nm.NewSelection = &dat->SelectedItems;
						SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm);
					}
					break;

				case TVN_DELETEITEM:
					if (dat->Items.GetSize()) { // if Items size = 0, then this TVN_DELETEITEM came after WM_DESTROY, so there is no need to do anything
						LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam;
						TREEITEMARRAY OldSelection = dat->SelectedItems;
						int Index = dat->SelectedItems.Find(pnmtv->itemOld.hItem);
						if (Index != -1)
							dat->SelectedItems.RemoveElem(Index);

						// find an item to pass to SelectGroups()
						HTREEITEM hItem = TreeView_GetNextSibling(dat->hTreeView, pnmtv->itemOld.hItem);
						if (!hItem) {
							hItem = TreeView_GetPrevSibling(dat->hTreeView, pnmtv->itemOld.hItem);
							if (!hItem)
								hItem = TreeView_GetParent(dat->hTreeView, pnmtv->itemOld.hItem);
						}
						if (hItem) // if it wasn't one of the root items
							dat->SelectGroups(hItem, dat->SelectedItems.Find(hItem) != -1);

						NMCLIST nm;
						nm.hdr.code = MCLN_SELCHANGED;
						nm.hdr.hwndFrom = dat->hTreeView;
						nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView);
						nm.OldSelection = &OldSelection;
						nm.NewSelection = &dat->SelectedItems;
						SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm);
						dat->Items[pnmtv->itemOld.lParam].hContact = INVALID_CONTACT_ID;
					}
					break;

				case NM_CUSTOMDRAW:
					LPNMTVCUSTOMDRAW lpNMCD = (LPNMTVCUSTOMDRAW)lParam;
					switch (lpNMCD->nmcd.dwDrawStage) {
					case CDDS_PREPAINT: // the control is about to start painting
						return CDRF_NOTIFYITEMDRAW; // instruct the control to return information when it draws items
					case CDDS_ITEMPREPAINT:
						return CDRF_NOTIFYPOSTPAINT;
					case CDDS_ITEMPOSTPAINT:
						RECT rc;
						if (TreeView_GetItemRect(dat->hTreeView, (HTREEITEM)lpNMCD->nmcd.dwItemSpec, &rc, false)) {
							for (int i = 0; i < MAXEXTRAICONS; i++) {
								BYTE nIndex = dat->Items[lpNMCD->nmcd.lItemlParam].ExtraIcons[i];
								if (nIndex != CLC_EXTRAICON_EMPTY) {
									ImageList_DrawEx(dat->ExtraImageList, nIndex, lpNMCD->nmcd.hdc, rc.right - EXTRAICON_XSTEP * (i + 1), rc.top, 0, 0, /*GetSysColor(COLOR_WINDOW)*/CLR_NONE, CLR_NONE, ILD_NORMAL);
								}
							}
						}
						break;
					}
				}
				break;
			}
		}
	}
	return CallWindowProc(dat->OrigParentProc, hWnd, Msg, wParam, lParam);
}
Example #22
0
bool TreeCtrl::GetItemRect(HTREEITEM item, bool fItemRect, RECT& r) {
    BOOL ok = TreeView_GetItemRect(this->hwnd, item, &r, (BOOL)fItemRect);
    return fromBOOL(ok);
}
Example #23
0
LRESULT CALLBACK ContactListSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	TVITEM tvi;
	CCList *dat = CWndUserData(GetParent(hWnd)).GetCList();

	switch (Msg) {
	case INTM_CONTACTDELETED: // wParam = (HANDLE)hContact
		{
			HTREEITEM hItem = dat->FindContact(wParam);
			if (hItem)
				TreeView_DeleteItem(hWnd, hItem);
		}
		break;

	case INTM_ICONCHANGED: // wParam = (HANDLE)hContact, lParam = IconID
		tvi.hItem = dat->FindContact(wParam);
		if (tvi.hItem) {
			tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
			tvi.iImage = tvi.iSelectedImage = lParam;
			TreeView_SetItem(hWnd, &tvi);
			dat->SortContacts();
			InvalidateRect(hWnd, nullptr, false);
		}
		break;

	case INTM_INVALIDATE:
		InvalidateRect(hWnd, nullptr, true);
		break;

	case WM_RBUTTONDOWN:
		SetFocus(hWnd);
		{
			TVHITTESTINFO hitTest;
			hitTest.pt.x = (short)LOWORD(lParam);
			hitTest.pt.y = (short)HIWORD(lParam);
			TreeView_HitTest(hWnd, &hitTest);
			if (hitTest.hItem && hitTest.flags & TVHT_ONITEM)
				TreeView_SelectItem(hWnd, hitTest.hItem);
		}
		return DefWindowProc(hWnd, Msg, wParam, lParam);

	case WM_LBUTTONDOWN:
		{
			POINT pt = { (short)LOWORD(lParam), (short)HIWORD(lParam) };
			DWORD hitFlags;
			HTREEITEM hItem = dat->HitTest(&pt, &hitFlags);
			if (!hItem)
				break;

			if (hitFlags & MCLCHT_ONITEMICON) {
				if (TreeView_GetChild(hWnd, hItem)) { // if it's a group, then toggle its state
					NMTREEVIEW nmtv;
					nmtv.hdr.hwndFrom = hWnd;
					nmtv.hdr.idFrom = GetDlgCtrlID(hWnd);
					nmtv.hdr.code = TVN_ITEMEXPANDING;
					nmtv.action = TVE_TOGGLE;
					nmtv.itemNew.hItem = hItem;
					nmtv.itemNew.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;
					TreeView_GetItem(hWnd, &nmtv.itemNew);
					nmtv.ptDrag = pt;
					if (SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmtv))
						return 0;

					HTREEITEM hOldSelItem = TreeView_GetSelection(hWnd);
					TreeView_Expand(hWnd, hItem, TVE_TOGGLE);
					HTREEITEM hNewSelItem = TreeView_GetSelection(hWnd);
					if (hNewSelItem != hOldSelItem) {
						TreeView_SetItemState(hWnd, hOldSelItem, (dat->SelectedItems.Find(hOldSelItem) == -1) ? 0 : TVIS_SELECTED, TVIS_SELECTED);
						TreeView_SetItemState(hWnd, hNewSelItem, (dat->SelectedItems.Find(hNewSelItem) == -1) ? 0 : TVIS_SELECTED, TVIS_SELECTED);
					}
					nmtv.hdr.code = TVN_ITEMEXPANDED;
					TreeView_GetItem(hWnd, &nmtv.itemNew);
					SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmtv);
					return 0;
				}
			}
			if (hitFlags & MCLCHT_ONITEM) {
				if (wParam & MK_CONTROL) {
					SetFocus(hWnd);
					TREEITEMARRAY OldSelection = dat->SelectedItems;
					int nIndex = dat->SelectedItems.Find(hItem);
					if (nIndex == -1) {
						TreeView_SetItemState(hWnd, hItem, TVIS_SELECTED, TVIS_SELECTED);
						dat->SelectedItems.AddElem(hItem);
					}
					else {
						TreeView_SetItemState(hWnd, hItem, 0, TVIS_SELECTED);
						dat->SelectedItems.RemoveElem(nIndex);
					}
					dat->SelectGroups(hItem, nIndex == -1);
					NMCLIST nm;
					nm.hdr.code = MCLN_SELCHANGED;
					nm.hdr.hwndFrom = hWnd;
					nm.hdr.idFrom = GetDlgCtrlID(hWnd);
					nm.OldSelection = &OldSelection;
					nm.NewSelection = &dat->SelectedItems;
					SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm);
					return 0;
				}
				// if it was a click on the selected item and there's need to do something in this case, then send SELCHANGED notification by ourselves, as the tree control doesn't do anything
				if (hItem == TreeView_GetSelection(hWnd) && (dat->SelectedItems.GetSize() != 1 || (dat->SelectedItems.GetSize() == 1 && dat->SelectedItems[0] != hItem))) {
					TreeView_SetItemState(hWnd, hItem, TVIS_SELECTED, TVIS_SELECTED);
					NMTREEVIEW nm = {};
					nm.hdr.code = TVN_SELCHANGED;
					nm.hdr.hwndFrom = hWnd;
					nm.hdr.idFrom = GetDlgCtrlID(hWnd);
					nm.itemOld.hItem = TreeView_GetSelection(hWnd);
					nm.itemOld.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;
					TreeView_GetItem(hWnd, &nm.itemOld);
					nm.itemNew = nm.itemOld;
					SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm);
				}
			}
		}
		break;

	case WM_SETFOCUS:
	case WM_KILLFOCUS:
		for (int i = 0; i < dat->SelectedItems.GetSize(); i++) {
			RECT rc;
			if (TreeView_GetItemRect(hWnd, dat->SelectedItems[i], &rc, false))
				InvalidateRect(hWnd, &rc, false);
		}
		break;

	case WM_SIZE:
	case WM_HSCROLL:
		InvalidateRect(hWnd, nullptr, false);
		break;

	case WM_MEASUREITEM:
		if (!wParam) // if the message was sent by a menu
			return Menu_MeasureItem(lParam);
		break;

	case WM_DRAWITEM:
		if (!wParam) // if the message was sent by a menu
			return Menu_DrawItem(lParam);
		break;

	case WM_CONTEXTMENU:
		{
			POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
			HTREEITEM hItem = nullptr;
			if (pt.x == -1 && pt.y == -1) {
				if (dat->SelectedItems.GetSize() == 1) {
					hItem = dat->SelectedItems[0];
					TreeView_EnsureVisible(hWnd, hItem);
					RECT rc;
					TreeView_GetItemRect(hWnd, hItem, &rc, true);
					pt.x = rc.left;
					pt.y = rc.bottom;
				}
			}
			else {
				DWORD hitFlags;
				ScreenToClient(hWnd, &pt);
				hItem = dat->HitTest(&pt, &hitFlags);
				if (!(hitFlags & MCLCHT_ONITEM))
					hItem = nullptr;
			}
			if (hItem) {
				MCONTACT hContact = dat->GetItemData(hItem).hContact;
				if (IsHContactContact(hContact)) {
					HMENU hMenu = Menu_BuildContactMenu(hContact);
					if (hMenu) {
						ClientToScreen(hWnd, &pt);
						Clist_MenuProcessCommand(TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, nullptr), MPCF_CONTACTMENU, hContact);
						DestroyMenu(hMenu);
						return 0;
					}
				}
			}
		}
		break;

	case WM_DESTROY:
		if (dat->ExtraImageList)
			ImageList_Destroy(dat->ExtraImageList);
		dat->SelectedItems.RemoveAll();
		dat->Items.RemoveAll();
		break;
	}
	return CallWindowProc(dat->OrigTreeViewProc, hWnd, Msg, wParam, lParam);
}
Example #24
0
/*******************************************************************************
 *
 *  FUNCTION: ChildWndProc(HWND, unsigned, WORD, LONG)
 *
 *  PURPOSE:  Processes messages for the child windows.
 *
 *  WM_COMMAND  - process the application menu
 *  WM_PAINT    - Paint the main window
 *  WM_DESTROY  - post a quit message and return
 *
 */
LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    BOOL Result;

    switch (message)
    {
    case WM_CREATE:
    {
        WNDPROC oldproc;
        HFONT hFont;
        WCHAR buffer[MAX_PATH];

        /* Load "My Computer" string */
        LoadStringW(hInst, IDS_MY_COMPUTER, buffer, COUNT_OF(buffer));

        g_pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd));
        if (!g_pChildWnd) return 0;

        wcsncpy(g_pChildWnd->szPath, buffer, MAX_PATH);
        g_pChildWnd->nSplitPos = 250;
        g_pChildWnd->hWnd = hWnd;
        g_pChildWnd->hAddressBarWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Edit", NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP,
                                                      CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                                                      hWnd, (HMENU)0, hInst, 0);
        g_pChildWnd->hAddressBtnWnd = CreateWindowExW(0, L"Button", L"»", WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_TEXT | BS_CENTER | BS_VCENTER | BS_FLAT | BS_DEFPUSHBUTTON,
                                                      CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                                                      hWnd, (HMENU)0, hInst, 0);
        g_pChildWnd->hTreeWnd = CreateTreeView(hWnd, g_pChildWnd->szPath, (HMENU) TREE_WINDOW);
        g_pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, g_pChildWnd->szPath*/);
        SetFocus(g_pChildWnd->hTreeWnd);

        /* set the address bar and button font */
        if ((g_pChildWnd->hAddressBarWnd) && (g_pChildWnd->hAddressBtnWnd))
        {
            hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
            SendMessageW(g_pChildWnd->hAddressBarWnd,
                         WM_SETFONT,
                         (WPARAM)hFont,
                         0);
            SendMessageW(g_pChildWnd->hAddressBtnWnd,
                         WM_SETFONT,
                         (WPARAM)hFont,
                         0);
        }
        /* Subclass the AddressBar */
        oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWLP_WNDPROC);
        SetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWLP_USERDATA, (DWORD_PTR)oldproc);
        SetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWLP_WNDPROC, (DWORD_PTR)AddressBarProc);
        break;
    }
    case WM_COMMAND:
        if(HIWORD(wParam) == BN_CLICKED)
        {
            PostMessageW(g_pChildWnd->hAddressBarWnd, WM_KEYUP, VK_RETURN, 0);
        }

        if (!_CmdWndProc(hWnd, message, wParam, lParam))
        {
            goto def;
        }
        break;
    case WM_PAINT:
        OnPaint(hWnd);
        return 0;
    case WM_SETCURSOR:
        if (LOWORD(lParam) == HTCLIENT)
        {
            POINT pt;
            GetCursorPos(&pt);
            ScreenToClient(hWnd, &pt);
            if (pt.x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && pt.x<g_pChildWnd->nSplitPos+SPLIT_WIDTH/2+1)
            {
                SetCursor(LoadCursorW(0, IDC_SIZEWE));
                return TRUE;
            }
        }
        goto def;
    case WM_DESTROY:
        DestroyTreeView();
        DestroyListView(g_pChildWnd->hListWnd);
        DestroyMainMenu();
        HeapFree(GetProcessHeap(), 0, g_pChildWnd);
        g_pChildWnd = NULL;
        PostQuitMessage(0);
        break;
    case WM_LBUTTONDOWN:
    {
        RECT rt;
        int x = (short)LOWORD(lParam);
        GetClientRect(hWnd, &rt);
        if (x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && x<g_pChildWnd->nSplitPos+SPLIT_WIDTH/2+1)
        {
            last_split = g_pChildWnd->nSplitPos;
            draw_splitbar(hWnd, last_split);
            SetCapture(hWnd);
        }
        break;
    }

    case WM_LBUTTONUP:
    case WM_RBUTTONDOWN:
        if (GetCapture() == hWnd)
        {
            finish_splitbar(hWnd, LOWORD(lParam));
        }
        break;

    case WM_CAPTURECHANGED:
        if (GetCapture()==hWnd && last_split>=0)
            draw_splitbar(hWnd, last_split);
        break;

    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
            if (GetCapture() == hWnd)
            {
                RECT rt;
                draw_splitbar(hWnd, last_split);
                GetClientRect(hWnd, &rt);
                ResizeWnd(rt.right, rt.bottom);
                last_split = -1;
                ReleaseCapture();
                SetCursor(LoadCursorW(0, IDC_ARROW));
            }
        break;

    case WM_MOUSEMOVE:
        if (GetCapture() == hWnd)
        {
            HDC hdc;
            RECT rt;
            HGDIOBJ OldObj;
            int x = LOWORD(lParam);
            if(!SizingPattern)
            {
                const DWORD Pattern[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
                SizingPattern = CreateBitmap(8, 8, 1, 1, Pattern);
            }
            if(!SizingBrush)
            {
                SizingBrush = CreatePatternBrush(SizingPattern);
            }

            GetClientRect(hWnd, &rt);
            x = (SHORT) min(max(x, SPLIT_MIN), rt.right - SPLIT_MIN);
            if(last_split != x)
            {
                rt.left = last_split-SPLIT_WIDTH/2;
                rt.right = last_split+SPLIT_WIDTH/2+1;
                hdc = GetDC(hWnd);
                OldObj = SelectObject(hdc, SizingBrush);
                PatBlt(hdc, rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, PATINVERT);
                last_split = x;
                rt.left = x-SPLIT_WIDTH/2;
                rt.right = x+SPLIT_WIDTH/2+1;
                PatBlt(hdc, rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, PATINVERT);
                SelectObject(hdc, OldObj);
                ReleaseDC(hWnd, hdc);
            }
        }
        break;

    case WM_SETFOCUS:
        if (g_pChildWnd != NULL)
        {
            SetFocus(g_pChildWnd->nFocusPanel? g_pChildWnd->hListWnd: g_pChildWnd->hTreeWnd);
        }
        break;

    case WM_TIMER:
        break;

    case WM_NOTIFY:
        if ((int)wParam == TREE_WINDOW && g_pChildWnd != NULL)
        {
            switch (((LPNMHDR)lParam)->code)
            {
            case TVN_ITEMEXPANDING:
                return !OnTreeExpanding(g_pChildWnd->hTreeWnd, (NMTREEVIEW*)lParam);
            case TVN_SELCHANGED:
                UpdateAddress(((NMTREEVIEW*)lParam)->itemNew.hItem, NULL, NULL);
                break;
            case NM_SETFOCUS:
                g_pChildWnd->nFocusPanel = 0;
                break;
            case TVN_BEGINLABELEDIT:
            {
                LPNMTVDISPINFO ptvdi;
                /* cancel label edit for rootkeys  */
                ptvdi = (LPNMTVDISPINFO) lParam;
                if (!TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem) ||
                    !TreeView_GetParent(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem)))
                    return TRUE;
                break;
            }
            case TVN_ENDLABELEDIT:
            {
                LPCWSTR keyPath;
                HKEY hRootKey;
                HKEY hKey = NULL;
                LPNMTVDISPINFO ptvdi;
                LONG lResult = TRUE;
                WCHAR szBuffer[MAX_PATH];

                ptvdi = (LPNMTVDISPINFO) lParam;
                if (ptvdi->item.pszText)
                {
                    keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey);
                    _snwprintf(szBuffer, COUNT_OF(szBuffer), L"%s\\%s", keyPath, ptvdi->item.pszText);
                    keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey);
                    if (RegOpenKeyExW(hRootKey, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
                    {
                        lResult = FALSE;
                        RegCloseKey(hKey);
                        (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, ptvdi->item.hItem);
                    }
                    else
                    {
                        if (RenameKey(hRootKey, keyPath, ptvdi->item.pszText) != ERROR_SUCCESS)
                            lResult = FALSE;
                        else
                            UpdateAddress(ptvdi->item.hItem, hRootKey, szBuffer);
                    }
                    return lResult;
                }
            }
            default:
                return 0;
            }
        }
        else
        {
            if ((int)wParam == LIST_WINDOW && g_pChildWnd != NULL)
            {
                switch (((LPNMHDR)lParam)->code)
                {
                case NM_SETFOCUS:
                    g_pChildWnd->nFocusPanel = 1;
                    break;
                default:
                    if(!ListWndNotifyProc(g_pChildWnd->hListWnd, wParam, lParam, &Result))
                    {
                        goto def;
                    }
                    return Result;
                    break;
                }
            }
        }
        break;

    case WM_CONTEXTMENU:
    {
        POINT pt;
        if((HWND)wParam == g_pChildWnd->hListWnd)
        {
            int i, cnt;
            BOOL IsDefault;
            pt.x = (short) LOWORD(lParam);
            pt.y = (short) HIWORD(lParam);
            cnt = ListView_GetSelectedCount(g_pChildWnd->hListWnd);
            i = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_FOCUSED | LVNI_SELECTED);
            if (pt.x == -1 && pt.y == -1)
            {
                RECT rc;
                if (i != -1)
                {
                    rc.left = LVIR_BOUNDS;
                    SendMessageW(g_pChildWnd->hListWnd, LVM_GETITEMRECT, i, (LPARAM) &rc);
                    pt.x = rc.left + 8;
                    pt.y = rc.top + 8;
                }
                else
                    pt.x = pt.y = 0;
                ClientToScreen(g_pChildWnd->hListWnd, &pt);
            }
            if(i == -1)
            {
                TrackPopupMenu(GetSubMenu(hPopupMenus, PM_NEW), TPM_RIGHTBUTTON, pt.x, pt.y, 0, hFrameWnd, NULL);
            }
            else
            {
                HMENU mnu = GetSubMenu(hPopupMenus, PM_MODIFYVALUE);
                SetMenuDefaultItem(mnu, ID_EDIT_MODIFY, MF_BYCOMMAND);
                IsDefault = IsDefaultValue(g_pChildWnd->hListWnd, i);
                if(cnt == 1)
                    EnableMenuItem(mnu, ID_EDIT_RENAME, MF_BYCOMMAND | (IsDefault ? MF_DISABLED | MF_GRAYED : MF_ENABLED));
                else
                    EnableMenuItem(mnu, ID_EDIT_RENAME, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
                EnableMenuItem(mnu, ID_EDIT_MODIFY, MF_BYCOMMAND | (cnt == 1 ? MF_ENABLED : MF_DISABLED | MF_GRAYED));
                EnableMenuItem(mnu, ID_EDIT_MODIFY_BIN, MF_BYCOMMAND | (cnt == 1 ? MF_ENABLED : MF_DISABLED | MF_GRAYED));

                TrackPopupMenu(mnu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hFrameWnd, NULL);
            }
        }
        else if ((HWND)wParam == g_pChildWnd->hTreeWnd)
        {
            TVHITTESTINFO hti;
            HMENU hContextMenu;
            TVITEMW item;
            MENUITEMINFOW mii;
            WCHAR resource[256];
            WCHAR buffer[256];
            LPWSTR s;
            LPCWSTR keyPath;
            HKEY hRootKey;
            int iLastPos;
            WORD wID;

            pt.x = (short) LOWORD(lParam);
            pt.y = (short) HIWORD(lParam);

            if (pt.x == -1 && pt.y == -1)
            {
                RECT rc;
                hti.hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
                if (hti.hItem != NULL)
                {
                    TreeView_GetItemRect(g_pChildWnd->hTreeWnd, hti.hItem, &rc, TRUE);
                    pt.x = rc.left + 8;
                    pt.y = rc.top + 8;
                    ClientToScreen(g_pChildWnd->hTreeWnd, &pt);
                    hti.flags = TVHT_ONITEM;
                }
                else
                    hti.flags = 0;
            }
            else
            {
                hti.pt.x = pt.x;
                hti.pt.y = pt.y;
                ScreenToClient(g_pChildWnd->hTreeWnd, &hti.pt);
                (void)TreeView_HitTest(g_pChildWnd->hTreeWnd, &hti);
            }

            if (hti.flags & TVHT_ONITEM)
            {
                hContextMenu = GetSubMenu(hPopupMenus, PM_TREECONTEXT);
                (void)TreeView_SelectItem(g_pChildWnd->hTreeWnd, hti.hItem);

                memset(&item, 0, sizeof(item));
                item.mask = TVIF_STATE | TVIF_CHILDREN;
                item.hItem = hti.hItem;
                (void)TreeView_GetItem(g_pChildWnd->hTreeWnd, &item);

                /* Set the Expand/Collapse menu item appropriately */
                LoadStringW(hInst, (item.state & TVIS_EXPANDED) ? IDS_COLLAPSE : IDS_EXPAND, buffer, COUNT_OF(buffer));
                memset(&mii, 0, sizeof(mii));
                mii.cbSize = sizeof(mii);
                mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID;
                mii.fState = (item.cChildren > 0) ? MFS_DEFAULT : MFS_GRAYED;
                mii.wID = (item.state & TVIS_EXPANDED) ? ID_TREE_COLLAPSEBRANCH : ID_TREE_EXPANDBRANCH;
                mii.dwTypeData = (LPWSTR) buffer;
                SetMenuItemInfo(hContextMenu, 0, TRUE, &mii);

                /* Remove any existing suggestions */
                memset(&mii, 0, sizeof(mii));
                mii.cbSize = sizeof(mii);
                mii.fMask = MIIM_ID;
                GetMenuItemInfo(hContextMenu, GetMenuItemCount(hContextMenu) - 1, TRUE, &mii);
                if ((mii.wID >= ID_TREE_SUGGESTION_MIN) && (mii.wID <= ID_TREE_SUGGESTION_MAX))
                {
                    do
                    {
                        iLastPos = GetMenuItemCount(hContextMenu) - 1;
                        GetMenuItemInfo(hContextMenu, iLastPos, TRUE, &mii);
                        RemoveMenu(hContextMenu, iLastPos, MF_BYPOSITION);
                    }
                    while((mii.wID >= ID_TREE_SUGGESTION_MIN) && (mii.wID <= ID_TREE_SUGGESTION_MAX));
                }

                /* Come up with suggestions */
                keyPath = GetItemPath(g_pChildWnd->hTreeWnd, NULL, &hRootKey);
                SuggestKeys(hRootKey, keyPath, Suggestions, COUNT_OF(Suggestions));
                if (Suggestions[0])
                {
                    AppendMenu(hContextMenu, MF_SEPARATOR, 0, NULL);

                    LoadStringW(hInst, IDS_GOTO_SUGGESTED_KEY, resource, COUNT_OF(resource));

                    s = Suggestions;
                    wID = ID_TREE_SUGGESTION_MIN;
                    while(*s && (wID <= ID_TREE_SUGGESTION_MAX))
                    {
                        _snwprintf(buffer, COUNT_OF(buffer), resource, s);

                        memset(&mii, 0, sizeof(mii));
                        mii.cbSize = sizeof(mii);
                        mii.fMask = MIIM_STRING | MIIM_ID;
                        mii.wID = wID++;
                        mii.dwTypeData = buffer;
                        InsertMenuItem(hContextMenu, GetMenuItemCount(hContextMenu), TRUE, &mii);

                        s += wcslen(s) + 1;
                    }
                }
                TrackPopupMenu(hContextMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, g_pChildWnd->hWnd, NULL);
            }
        }
        break;
    }

    case WM_SIZE:
        if (wParam != SIZE_MINIMIZED && g_pChildWnd != NULL)
        {
            ResizeWnd(LOWORD(lParam), HIWORD(lParam));
        }
        /* fall through */
    default:
def:
        return DefWindowProcW(hWnd, message, wParam, lParam);
    }
    return 0;
}
static void RelayoutTocItem(LPNMTVCUSTOMDRAW ntvcd)
{
    // code inspired by http://www.codeguru.com/cpp/controls/treeview/multiview/article.php/c3985/
    LPNMCUSTOMDRAW ncd = &ntvcd->nmcd;
    HWND hTV = ncd->hdr.hwndFrom;
    HTREEITEM hItem = (HTREEITEM)ncd->dwItemSpec;
    RECT rcItem;
    if (0 == ncd->rc.right - ncd->rc.left || 0 == ncd->rc.bottom - ncd->rc.top)
        return;
    if (!TreeView_GetItemRect(hTV, hItem, &rcItem, TRUE))
        return;
    if (rcItem.right > ncd->rc.right)
        rcItem.right = ncd->rc.right;

    // Clear the label
    RECT rcFullWidth = rcItem;
    rcFullWidth.right = ncd->rc.right;
    FillRect(ncd->hdc, &rcFullWidth, GetSysColorBrush(COLOR_WINDOW));

    // Get the label's text
    WCHAR szText[MAX_PATH];
    TVITEM item;
    item.hItem = hItem;
    item.mask = TVIF_TEXT | TVIF_PARAM;
    item.pszText = szText;
    item.cchTextMax = MAX_PATH;
    TreeView_GetItem(hTV, &item);

    // Draw the page number right-aligned (if there is one)
    WindowInfo *win = FindWindowInfoByHwnd(hTV);
    DocTocItem *tocItem = (DocTocItem *)item.lParam;
    ScopedMem<WCHAR> label;
    if (tocItem->pageNo && win && win->IsDocLoaded()) {
        label.Set(win->ctrl->GetPageLabel(tocItem->pageNo));
        label.Set(str::Join(L"  ", label));
    }
    if (label && str::EndsWith(item.pszText, label)) {
        RECT rcPageNo = rcFullWidth;
        InflateRect(&rcPageNo, -2, -1);

        SIZE txtSize;
        GetTextExtentPoint32(ncd->hdc, label, str::Len(label), &txtSize);
        rcPageNo.left = rcPageNo.right - txtSize.cx;

        SetTextColor(ncd->hdc, GetSysColor(COLOR_WINDOWTEXT));
        SetBkColor(ncd->hdc, GetSysColor(COLOR_WINDOW));
        DrawText(ncd->hdc, label, -1, &rcPageNo, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);

        // Reduce the size of the label and cut off the page number
        rcItem.right = std::max(rcItem.right - txtSize.cx, 0);
        szText[str::Len(szText) - str::Len(label)] = '\0';
    }

    SetTextColor(ncd->hdc, ntvcd->clrText);
    SetBkColor(ncd->hdc, ntvcd->clrTextBk);

    // Draw the focus rectangle (including proper background color)
    HBRUSH brushBg = CreateSolidBrush(ntvcd->clrTextBk);
    FillRect(ncd->hdc, &rcItem, brushBg);
    DeleteObject(brushBg);
    if ((ncd->uItemState & CDIS_FOCUS))
        DrawFocusRect(ncd->hdc, &rcItem);

    InflateRect(&rcItem, -2, -1);
    DrawText(ncd->hdc, szText, -1, &rcItem, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_WORD_ELLIPSIS);
}
Example #26
0
/*
* MainWindowProc
*
* Purpose:
*
* Main window procedure.
*
*/
LRESULT CALLBACK MainWindowProc(
    _In_ HWND hwnd,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
)
{
    INT                 mark;
    RECT                ToolBarRect, crc;
    LPDRAWITEMSTRUCT    pds;
    LPMEASUREITEMSTRUCT pms;

    switch (uMsg) {
    case WM_CONTEXTMENU:

        RtlSecureZeroMemory(&crc, sizeof(crc));

        if ((HWND)wParam == g_hwndObjectTree) {
            TreeView_GetItemRect(g_hwndObjectTree, TreeView_GetSelection(g_hwndObjectTree), &crc, TRUE);
            crc.top = crc.bottom;
            ClientToScreen(g_hwndObjectTree, (LPPOINT)&crc);
            supHandleTreePopupMenu(hwnd, (LPPOINT)&crc);
        }

        if ((HWND)wParam == g_hwndObjectList) {
            mark = ListView_GetSelectionMark(g_hwndObjectList);

            if (lParam == MAKELPARAM(-1, -1)) {
                ListView_GetItemRect(g_hwndObjectList, mark, &crc, TRUE);
                crc.top = crc.bottom;
                ClientToScreen(g_hwndObjectList, (LPPOINT)&crc);
            }
            else
                GetCursorPos((LPPOINT)&crc);

            supHandleObjectPopupMenu(hwnd, g_hwndObjectList, mark, (LPPOINT)&crc);
        }
        break;

    case WM_COMMAND:
        MainWindowHandleWMCommand(hwnd, wParam, lParam);
        break;

    case WM_NOTIFY:
        MainWindowHandleWMNotify(hwnd, wParam, lParam);
        break;

    case WM_MEASUREITEM:
        pms = (LPMEASUREITEMSTRUCT)lParam;
        if (pms && pms->CtlType == ODT_MENU) {
            pms->itemWidth = 16;
            pms->itemHeight = 16;
        }
        break;

    case WM_DRAWITEM:
        pds = (LPDRAWITEMSTRUCT)lParam;
        if (pds && pds->CtlType == ODT_MENU) {
            DrawIconEx(pds->hDC, pds->rcItem.left - 15,
                pds->rcItem.top,
                (HICON)pds->itemData,
                16, 16, 0, NULL, DI_NORMAL);
        }
        break;

    case WM_CLOSE:
        PostQuitMessage(0);
        break;

    case WM_LBUTTONDOWN:
        SetCapture(MainWindow);
        break;

    case WM_LBUTTONUP:
        ReleaseCapture();
        break;

    case WM_MOUSEMOVE:
        if ((wParam & MK_LBUTTON) != 0) {
            GetClientRect(MainWindow, &ToolBarRect);
            SplitterPos = (SHORT)LOWORD(lParam);
            if (SplitterPos < SplitterMargin)
                SplitterPos = SplitterMargin;
            if (SplitterPos > ToolBarRect.right - SplitterMargin)
                SplitterPos = ToolBarRect.right - SplitterMargin;
            SendMessage(MainWindow, WM_SIZE, 0, 0);
            UpdateWindow(MainWindow);
        }
        break;

    case WM_SIZE:
        if (!IsIconic(hwnd)) {
            MainWindowResizeHandler(SplitterPos);
        }
        break;

    case WM_GETMINMAXINFO:
        if (lParam) {
            ((PMINMAXINFO)lParam)->ptMinTrackSize.x = 400;
            ((PMINMAXINFO)lParam)->ptMinTrackSize.y = 256;
        }
        break;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
Example #27
0
static LRESULT CALLBACK WndProc (HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
	static bool bDragging = FALSE;

	switch (uMessage)
	{
	case WM_SETFOCUS:
	case WM_KILLFOCUS:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if ( window )
		{
			mxEvent event;
			event.event = mxEvent::Focus;
			event.widget = NULL;
			event.action = (uMessage == WM_SETFOCUS);
			RecursiveHandleEvent( window, &event );
			return 0;
		}
	}
	break;

	case WM_ACTIVATE:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if ( window )
		{
			mxEvent event;
			event.event = mxEvent::Activate;
			event.widget = NULL;
			event.action = (LOWORD( wParam ) != WA_INACTIVE);
			RecursiveHandleEvent( window, &event );
			return 0;
		}
	}
	break;

	case WM_COMMAND:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (LOWORD (wParam) > 0 && window)
		{
			WORD wNotifyCode = (WORD) HIWORD (wParam);
			HWND hwndCtrl = (HWND) lParam;
			mxEvent event;

			CHAR className[128];
			GetClassName (hwndCtrl, className, 128);
			if (!strcmpi (className, "edit"))
			{
				if (wNotifyCode != EN_CHANGE)
					break;
			}
			else if (!strcmpi (className, "combobox"))
			{
				if (wNotifyCode != CBN_SELCHANGE)
					break;
			}
			else if (!strcmpi (className, "listbox"))
			{
				if (wNotifyCode != LBN_SELCHANGE)
					break;
			}

			event.event = mxEvent::Action;
			event.widget = (mxWidget *) GetWindowLong ((HWND) lParam, GWL_USERDATA);
			event.action = (int) LOWORD (wParam);
			RecursiveHandleEvent( window, &event );
		}
	}
	break;

	case WM_NOTIFY:
	{
		if (isClosing)
			break;

		NMHDR *nmhdr = (NMHDR *) lParam;
		mxEvent event;

#if 0
		//if ( nmhdr->idFrom > 0 ) 
		{
			mxWidget *temp = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA);
			if ( temp && temp->getType() == MX_TREEVIEW )
			{
				NMTREEVIEW *nmt = ( NMTREEVIEW * )nmhdr;

				HTREEITEM hItem = TreeView_GetSelection (nmhdr->hwndFrom);

				char sz[ 256 ];
				sprintf( sz, "tree view receiving notify %i : %s action %i old %p new %p selection %p\n", nmhdr->code, translatecode( nmhdr->code ),
					nmt->action, nmt->itemOld, nmt->itemNew, hItem );
				
				OutputDebugString( sz );
			}
		}
#endif

		if (nmhdr->code == TVN_SELCHANGED)
		{
			if (nmhdr->idFrom > 0)
			{
				mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
				event.event = mxEvent::Action;
				event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA);
				event.action = (int) nmhdr->idFrom;

				RECT rc;
				HTREEITEM hItem = TreeView_GetSelection (nmhdr->hwndFrom);
				TreeView_GetItemRect (nmhdr->hwndFrom, hItem, &rc, TRUE);
				event.x = (int) rc.left;
				event.y = (int) rc.bottom;
				RecursiveHandleEvent( window, &event );

			}
		}
		else if (nmhdr->code == LVN_ITEMCHANGED)
		{
			if (nmhdr->idFrom > 0)
			{
				mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
				event.event = mxEvent::Action;
				event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA);
				event.action = (int) nmhdr->idFrom;

				RecursiveHandleEvent( window, &event );
			}
		}
		else if (nmhdr->code == NM_RCLICK)
		{
			if (nmhdr->idFrom > 0)
			{
				mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
				event.event = mxEvent::Action;
				event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA);
				event.action = (int) nmhdr->idFrom;
				event.flags = mxEvent::RightClicked;

				if ( event.widget )
				{
					if ( event.widget->getType () == MX_TREEVIEW )
					{
						RECT rc;
						HTREEITEM hItem = TreeView_GetSelection (nmhdr->hwndFrom);
						TreeView_GetItemRect (nmhdr->hwndFrom, hItem, &rc, TRUE);
						event.x = (int) rc.left;
						event.y = (int) rc.bottom;
					}
				}
				RecursiveHandleEvent( window, &event );
			}
		}
		else if (nmhdr->code == NM_DBLCLK)
		{
			if (nmhdr->idFrom > 0)
			{
				mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
				event.event = mxEvent::Action;
				event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA);
				event.action = (int) nmhdr->idFrom;
				event.flags = mxEvent::DoubleClicked;

				if (event.widget )
				{
					if ( event.widget->getType () == MX_TREEVIEW )
					{
						RECT rc;
						HTREEITEM hItem = TreeView_GetSelection (nmhdr->hwndFrom);
						TreeView_GetItemRect (nmhdr->hwndFrom, hItem, &rc, TRUE);
						event.x = (int) rc.left;
						event.y = (int) rc.bottom;
					}
				}

				RecursiveHandleEvent( window, &event );
				return TRUE;
			}
		}
		else if (nmhdr->code == TCN_SELCHANGING)
		{
			TC_ITEM ti;

			int index = TabCtrl_GetCurSel (nmhdr->hwndFrom);
			if (index >= 0)
			{
				ti.mask = TCIF_PARAM;
				TabCtrl_GetItem (nmhdr->hwndFrom, index, &ti);
				mxWindow *window = (mxWindow *) ti.lParam;
				if (window)
					window->setVisible (false);
			}
		}
		else if (nmhdr->code == TCN_SELCHANGE)
		{
			mxTab_resizeChild (nmhdr->hwndFrom);
			if (nmhdr->idFrom > 0)
			{
				mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
				event.event = mxEvent::Action;
				event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA);
				event.action = (int) nmhdr->idFrom;
				RecursiveHandleEvent( window, &event );
			}
		}
	}
	break;

	case WM_SIZE:
	{
		mxEvent event;

		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			event.event = mxEvent::Size;
			event.width = (int) LOWORD (lParam);
			event.height = (int) HIWORD (lParam);
			window->handleEvent (&event);
		}
	}
	break;
	case WM_WINDOWPOSCHANGED:
	{
		mxEvent event;

		
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			event.event = mxEvent::PosChanged;

			WINDOWPOS *wp = ( WINDOWPOS * )lParam;

			event.x			= wp->x;
			event.y			= wp->y;
			event.width		= wp->cx;
			event.height	= wp->cy;

			window->handleEvent (&event);
		}
	}
	break;

	case WM_ERASEBKGND:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			if (window->getType () == MX_GLWINDOW)
				return 0;
			if (window->getType () == MX_MATSYSWINDOW)
				return 0;

			if ( !isClosing && !window->PaintBackground() )
			{
				return 0;
			}
		}
	}
	break;

	case WM_HSCROLL:
	case WM_VSCROLL:
	{
		mxWidget *widget = (mxWidget *) GetWindowLong ((HWND) lParam, GWL_USERDATA);
		if (!widget)
		{
			break;
		}

		if (widget->getType() != MX_SCROLLBAR && widget->getType() != MX_SLIDER)
		{
			break;
		}


		switch (LOWORD (wParam))
		{
		case TB_LINEUP: // 	SB_LINEUP SB_LINELEFT
			break;
		case TB_LINEDOWN: // SB_LINEDOWN SB_LINERIGHT
			break;
		case TB_PAGEUP: // SB_PAGEUP SB_PAGELEFT
			break;
		case TB_PAGEDOWN: // SB_PAGEDOWN SB_PAGERIGHT
			break;
		case TB_THUMBPOSITION:  // SB_THUMBPOSITION
			break;
		case TB_THUMBTRACK: // SB_THUMBTRACK
			break;
		case TB_TOP: // SB_TOP SB_LEFT
			break;
		case TB_BOTTOM: // SB_BOTTOM SB_RIGHT
			break;
		case TB_ENDTRACK: // SB_ENDSCROLL
			break;
		default:
			break;
		}

		switch (LOWORD (wParam))
		{
		case TB_LINEUP: // 	SB_LINEUP SB_LINELEFT
		case TB_LINEDOWN: // SB_LINEDOWN SB_LINERIGHT
		case TB_PAGEUP: // SB_PAGEUP SB_PAGELEFT
		case TB_PAGEDOWN: // SB_PAGEDOWN SB_PAGERIGHT
		case TB_THUMBPOSITION:  // SB_THUMBPOSITION
		case TB_THUMBTRACK: // SB_THUMBTRACK
		case TB_TOP: // SB_TOP SB_LEFT
		case TB_BOTTOM: // SB_BOTTOM SB_RIGHT
		case TB_ENDTRACK: // SB_ENDSCROLL
		{
			mxEvent event;

			event.event = mxEvent::Action;
			event.widget = widget;
			event.action = widget->getId ();
			event.modifiers = LOWORD (wParam);
			event.height = HIWORD( wParam );
			mxWindow *window = widget->getParent ();

			if ( event.action > 0 )
			{
				RecursiveHandleEvent( window, &event );
			}
		}
		break;
		}
	}
	break;

	case WM_PAINT:
	{
		if ( !isClosing )
		{
			mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
			if (window)
			{
				window->redraw ();
			}
		}
	}
	break;

	case WM_PARENTNOTIFY:
		{
			mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
			if (window)
			{
				if ( wParam == WM_LBUTTONDOWN ||
					 wParam == WM_MBUTTONDOWN ||
					 wParam == WM_RBUTTONDOWN /*||
					 wParam & WM_XBUTTONDOWN*/ )
				{
					mxEvent event;
					event.event = mxEvent::ParentNotify;
					event.x = (short)LOWORD (lParam);
					event.y = (short)HIWORD (lParam);
					event.buttons = 0;
					event.modifiers = 0;

					if ( wParam == WM_LBUTTONDOWN )
						event.buttons |= mxEvent::MouseLeftButton;

					if ( wParam == WM_RBUTTONDOWN )
						event.buttons |= mxEvent::MouseRightButton;

					if ( wParam == WM_MBUTTONDOWN )
						event.buttons |= mxEvent::MouseMiddleButton;

					window->handleEvent (&event);
					RecursiveHandleEvent( window, &event );
					return 0;
				}
			}
		}
		break;

	case WM_LBUTTONDOWN:
	case WM_MBUTTONDOWN:
	case WM_RBUTTONDOWN:
	{
		bDragging = TRUE;
		SetCapture (hwnd);
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);

		if (window)
		{
			mxEvent event;
			event.event = mxEvent::MouseDown;
			event.x = (short)LOWORD (lParam);
			event.y = (short)HIWORD (lParam);
			event.buttons = 0;
			event.modifiers = 0;

			if (uMessage == WM_MBUTTONDOWN)
				event.buttons |= mxEvent::MouseMiddleButton;
			else if (uMessage == WM_RBUTTONDOWN)
				event.buttons |= mxEvent::MouseRightButton;
			else
				event.buttons |= mxEvent::MouseLeftButton;

			if (wParam & MK_LBUTTON)
				event.buttons |= mxEvent::MouseLeftButton;

			if (wParam & MK_RBUTTON)
				event.buttons |= mxEvent::MouseRightButton;

			if (wParam & MK_MBUTTON)
				event.buttons |= mxEvent::MouseMiddleButton;

			if (wParam & MK_CONTROL)
				event.modifiers |= mxEvent::KeyCtrl;

			if (wParam & MK_SHIFT)
				event.modifiers |= mxEvent::KeyShift;

			window->handleEvent (&event);
		}
	}
	break;

	case WM_LBUTTONUP:
	case WM_MBUTTONUP:
	case WM_RBUTTONUP:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			mxEvent event;
			event.event = mxEvent::MouseUp;
			event.x = (short) LOWORD (lParam);
			event.y = (short) HIWORD (lParam);
			event.buttons = 0;
			event.modifiers = 0;

			if (uMessage == WM_MBUTTONUP)
				event.buttons |= mxEvent::MouseMiddleButton;
			else if (uMessage == WM_RBUTTONUP)
				event.buttons |= mxEvent::MouseRightButton;
			else
				event.buttons |= mxEvent::MouseLeftButton;

			if (wParam & MK_LBUTTON)
				event.buttons |= mxEvent::MouseLeftButton;

			if (wParam & MK_RBUTTON)
				event.buttons |= mxEvent::MouseRightButton;

			if (wParam & MK_MBUTTON)
				event.buttons |= mxEvent::MouseMiddleButton;

			if (wParam & MK_CONTROL)
				event.modifiers |= mxEvent::KeyCtrl;

			if (wParam & MK_SHIFT)
				event.modifiers |= mxEvent::KeyShift;

			window->handleEvent (&event);
		}
		bDragging = FALSE;
		ReleaseCapture ();
	}
	break;

	case WM_MOUSEMOVE:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			mxEvent event;

			if (bDragging)
				event.event = mxEvent::MouseDrag;
			else
				event.event = mxEvent::MouseMove;

			event.x = (short) LOWORD (lParam);
			event.y = (short) HIWORD (lParam);
			event.buttons = 0;
			event.modifiers = 0;

			if (wParam & MK_LBUTTON)
				event.buttons |= mxEvent::MouseLeftButton;

			if (wParam & MK_RBUTTON)
				event.buttons |= mxEvent::MouseRightButton;

			if (wParam & MK_MBUTTON)
				event.buttons |= mxEvent::MouseMiddleButton;

			if (wParam & MK_CONTROL)
				event.modifiers |= mxEvent::KeyCtrl;

			if (wParam & MK_SHIFT)
				event.modifiers |= mxEvent::KeyShift;

			window->handleEvent (&event);
		}
	}
	break;
	case WM_NCLBUTTONDOWN:
	case WM_NCMBUTTONDOWN:
	case WM_NCRBUTTONDOWN:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);

		if (window)
		{
			mxEvent event;
			event.event = mxEvent::NCMouseDown;
			event.x = (short) LOWORD (lParam);
			event.y = (short) HIWORD (lParam);
			event.buttons = 0;
			event.modifiers = 0;

			if (uMessage == WM_NCMBUTTONDOWN)
				event.buttons |= mxEvent::MouseMiddleButton;
			else if (uMessage == WM_NCRBUTTONDOWN)
				event.buttons |= mxEvent::MouseRightButton;
			else
				event.buttons |= mxEvent::MouseLeftButton;

			window->handleEvent (&event);
		}
	}
	break;

	case WM_NCLBUTTONUP:
	case WM_NCMBUTTONUP:
	case WM_NCRBUTTONUP:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			mxEvent event;
			event.event = mxEvent::NCMouseUp;
			event.x = (short) LOWORD (lParam);
			event.y = (short) HIWORD (lParam);
			event.buttons = 0;
			event.modifiers = 0;

			if (uMessage == WM_NCMBUTTONUP)
				event.buttons |= mxEvent::MouseMiddleButton;
			else if (uMessage == WM_NCRBUTTONUP)
				event.buttons |= mxEvent::MouseRightButton;
			else
				event.buttons |= mxEvent::MouseLeftButton;

			window->handleEvent (&event);
		}
	}
	break;

	case WM_NCMOUSEMOVE:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			mxEvent event;

			event.event = mxEvent::NCMouseMove;

			event.x = (short) LOWORD (lParam);
			event.y = (short) HIWORD (lParam);
			event.buttons = 0;
			event.modifiers = 0;

			window->handleEvent (&event);
		}
	}
	break;

	case WM_KEYDOWN:
	case WM_SYSKEYDOWN:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			mxEvent event;
			event.event = mxEvent::KeyDown;
			event.key = (int) wParam;
			if ( window->handleEvent (&event) )
				return 0;
		}
	}
	break;

	case WM_CHAR:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			mxEvent event;
			event.event = mxEvent::Char;
			event.key = (int) wParam;
			if ( window->handleEvent (&event) )
				return 0;
		}
	}
	break;

	case WM_SYSCHAR:
		return 0;
		break;

	case WM_KEYUP:
	case WM_SYSKEYUP:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			mxEvent event;
			event.event = mxEvent::KeyUp;
			event.key = (int) wParam;
			if ( window->handleEvent (&event) )
				return 0;
		}
	}
	break;

	case WM_MOUSEWHEEL:
	{
		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			mxEvent event;
			memset( &event, 0, sizeof( event ) );
			event.event = mxEvent::MouseWheeled;
			event.x = (short) LOWORD (lParam);
			event.y = (short) HIWORD (lParam);

			if (wParam & MK_LBUTTON)
				event.buttons |= mxEvent::MouseLeftButton;

			if (wParam & MK_RBUTTON)
				event.buttons |= mxEvent::MouseRightButton;

			if (wParam & MK_MBUTTON)
				event.buttons |= mxEvent::MouseMiddleButton;

			if (wParam & MK_CONTROL)
				event.modifiers |= mxEvent::KeyCtrl;

			if (wParam & MK_SHIFT)
				event.modifiers |= mxEvent::KeyShift;

			event.height = (short)HIWORD( wParam );;
			RecursiveHandleEvent( window, &event );
		}
	}
	break;
	case WM_TIMER:
	{
		if (isClosing)
			break;

		mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
		if (window)
		{
			mxEvent event;
			event.event = mxEvent::Timer;
			window->handleEvent (&event);
		}
	}
	break;

	case WM_CLOSE:
		if (g_mainWindow)
		{
			if ((void *) hwnd == g_mainWindow->getHandle ())
			{
				mx::quit ();
			}
			else
			{
				ShowWindow (hwnd, SW_HIDE);

				mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA);
				if (window)
				{
					mxEvent event;
					event.event = mxEvent::Close;
					window->handleEvent( &event );
				}
			}
		}
		//else // shouldn't happen
			//DestroyWindow (hwnd);
		return 0;
/*
	case WM_DESTROY:
		if (g_mainWindow)
		{
			if ((void *) hwnd == g_mainWindow->getHandle ())
				mx::quit ();
		}
		break;
*/
	}

	return DefWindowProc (hwnd, uMessage, wParam, lParam);
}
Example #28
0
LRESULT CALLBACK extTreeWndProc(HWND hwnd, UINT iMessage, WPARAM wParam,
    LPARAM lParam)
{
    static char buf[256];
    LRESULT rv;
    RECT r;
    TREEINFO *ptr;
    HTREEITEM hTreeItem;
    TCData *td;
    TV_HITTESTINFO tvh;
    TV_ITEM item;
    NM_TREEVIEW x;
    switch (iMessage)
    {
        case WM_NOTIFY:
//            if (((NMHDR*)lParam)->code == TVN_SELCHANGING)
//
                return TRUE;
            break;
        case WM_CREATE:
            ptr = (TREEINFO*)calloc(1,sizeof(TREEINFO));
            ptr->hwndEdit = 0;
            SetWindowLong(hwnd, wndoffstree, (int)ptr);
            break;
        case WM_DESTROY:
            ptr = (TREEINFO*)GetWindowLong(hwnd, wndoffstree);
            if (ptr->hwndEdit)
                DestroyWindow(ptr->hwndEdit);
            free(ptr);
            break;
        case WM_ERASEBKGND:
            return 1;
        case WM_PAINT:
            GetUpdateRect(hwnd, &r, FALSE);
            {
                PAINTSTRUCT ps;
                HDC hDC = BeginPaint(hwnd, &ps), hdouble;
                HBITMAP bitmap;
                RECT rect;
                GetClientRect(hwnd, &rect);
                hdouble = CreateCompatibleDC(hDC);
                bitmap = CreateCompatibleBitmap(hDC, rect.right, rect.bottom);
                SelectObject(hdouble, bitmap);
                FillRect(hdouble,&rect, (HBRUSH)(COLOR_WINDOW + 1));
                CallWindowProc(oldproc, hwnd, WM_PRINT, (WPARAM)hdouble, PRF_CLIENT);
                SendMessage(GetParent(hwnd), TCN_PAINT, (WPARAM)hdouble, (LPARAM) &r);
                BitBlt(hDC, 0, 0, rect.right, rect.bottom, hdouble, 0, 0, SRCCOPY);
                DeleteObject(bitmap);
                DeleteDC(hdouble);
                EndPaint(hwnd, &ps);
                return 0;
            }
        case WM_KEYDOWN:
            if (wParam =='C' && (GetKeyState(VK_CONTROL) & 0x80000000))
            {
                CopyText(hwnd);
            }
            break;
        case WM_SETFOCUS:
            SendMessage(GetParent(hwnd), WM_ACTIVATEME, 0, 0);
            break;
        case WM_CHAR:
            if (wParam == 3) //CTRL-C - this is being done to stop beeping...
                return 0;
            break;
        case WM_LBUTTONDOWN:
            ptr = (TREEINFO*)GetWindowLong(hwnd, wndoffstree);
            if (!ptr->hwndEdit)
            {
                tvh.pt.x = LOWORD(lParam);
                tvh.pt.y = HIWORD(lParam);
                if (tvh.pt.x < ptr->divider)
                {
                    SetFocus(hwnd);
                    break;
                }
                TreeView_HitTest(hwnd, &tvh);
                hTreeItem = tvh.hItem;
                if (hTreeItem && tvh.pt.x >= ptr->divider)
                {
                    char *val;
                    x.hdr.code = TCN_EDITQUERY;
                    x.itemOld.mask = 0;
                    x.itemNew.mask = 0;
                    x.itemNew.hItem = hTreeItem;
                    if ((val = (char*)SendMessage(GetParent(hwnd), WM_NOTIFY, 0,
                        (LPARAM) &x)))
                    {
                        HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
                        ptr->editItem = hTreeItem;
                        TreeView_GetItemRect(hwnd, hTreeItem, &r, FALSE);
                        r.left = ptr->divider;
                        item.hItem = hTreeItem;
                        item.mask = TVIF_PARAM;
                        TreeView_GetItem(hwnd, &item);
                        td = (TCData*)item.lParam;
                        ptr->hwndEdit = CreateWindow(szextEditWindClassName,
                            val, WS_CHILD | ES_AUTOHSCROLL, r.left+2, r.top,
                            r.right - r.left-2, r.bottom - r.top, hwnd, (HMENU)
                            449, (HINSTANCE)GetWindowLong(GetParent(hwnd),
                            GWL_HINSTANCE), 0);
                        SendMessage(ptr->hwndEdit, WM_SETFONT, (WPARAM)font,
                            MAKELPARAM(0, 0));
                        SendMessage(ptr->hwndEdit, EM_SETSEL, 0, (LPARAM) - 1);
                        SendMessage(ptr->hwndEdit, EM_SETLIMITTEXT, 40, 0);
                        ShowWindow(ptr->hwndEdit, SW_SHOW);
                        SetFocus(ptr->hwndEdit);
                        return 0;
                    }
                }
                return 0;
            }
            // FALL THROUGH 
        case TCN_EDITDONE:
            ptr = (TREEINFO*)GetWindowLong(hwnd, wndoffstree);
            SendMessage(ptr->hwndEdit, WM_GETTEXT, 50, (LPARAM)buf);
            DestroyWindow(ptr->hwndEdit);
            ptr->hwndEdit = 0;
            x.hdr.code = TCN_EDITDONE;
            x.itemOld.mask = 0;
            x.itemNew.mask = TVIF_TEXT;
            x.itemNew.hItem = ptr->editItem;
            x.itemNew.pszText = buf;
            SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) &x);
            InvalidateRect(GetParent(hwnd), 0, 0);
            return 0;
        case TCF_SETDIVIDER:
            ptr = (TREEINFO*)GetWindowLong(hwnd, wndoffstree);
            ptr->divider = lParam - GetSystemMetrics(SM_CXBORDER);
            return 0;

    }
    return CallWindowProc(oldproc, hwnd, iMessage, wParam, lParam);
}
Example #29
0
LRESULT CALLBACK ColumnTreeWndProc(HWND hwnd, UINT iMessage, WPARAM
    wParam, LPARAM lParam)
{
    HTREEITEM titem;
    HD_LAYOUT hdl;
    WINDOWPOS wp;
    COLUMNINFO *ptr;
    RECT r,  *rp;
    HD_ITEM hie;
    TCHeader *h;
    HD_NOTIFY *n;
    TV_DISPINFO *t;
    LPTV_INSERTSTRUCT is;
    int i;
    TV_ITEM item;
    TCData *td;
    TV_HITTESTINFO tvh;
    TREEINFO *treeinfo;
    PAINTSTRUCT ps;
    HDC dc;
    NM_TREEVIEW *ntv;
    if (iMessage >= TV_FIRST && iMessage < TV_FIRST + 100)
    {
        ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
        switch (iMessage)
        {
            case TVM_HITTEST:
                tvh.pt = ((TV_HITTESTINFO*)lParam)->pt;
                ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
                GetRelativeRect(hwnd, ptr->hwndTree, &r);
                tvh.pt.x -= r.left;
                tvh.pt.y -= r.top;
                if ((titem = TreeView_HitTest(ptr->hwndTree, &tvh)))
                {
                    ((TV_HITTESTINFO*)lParam)->flags = tvh.flags;
                    ((TV_HITTESTINFO*)lParam)->hItem = tvh.hItem;
                }
                return (LRESULT)titem;
            case TVM_INSERTITEM:
                is = (LPTV_INSERTSTRUCT)lParam;
                is->UNNAMED_UNION item.mask |= TVIF_TEXT | TVIF_PARAM;
                is->UNNAMED_UNION item.pszText = LPSTR_TEXTCALLBACK;
                titem = (HTREEITEM)SendMessage(ptr->hwndTree, iMessage, wParam,
                    lParam);
                return (LRESULT)titem;
            default:
                return SendMessage(ptr->hwndTree, iMessage, wParam, lParam);
        }
    }
    else if (iMessage >= HDM_FIRST && iMessage < HDM_FIRST + 100)
    {
        ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
        return SendMessage(ptr->hwndHeader, iMessage, wParam, lParam);
    }
    switch (iMessage)
    {
        case WM_ERASEBKGND:
            return 1;
        case WM_NOTIFY:
            n = (HD_NOTIFY*)lParam;
            ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
            switch (n->hdr.code)
            {
            case NM_RCLICK:
                #ifdef XXXXX
                    ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
                    GetCursorPos(&pos);
                    ScreenToClient(ptr->hwndTree, &pos);
                    titem = TreeView_HitTest(ptr->hwndTree, &pos);
                    for (i = 0; i < ptr->displaycount; i++)
                    if (titem == ptr->displaylist[i])
                    {
                        ptr->sel = i;
                        InvalidateRect(ptr->hwndTree, 0, 0);
                        break;
                    }
                #endif 
                return SendMessage(GetParent(hwnd), iMessage, wParam, lParam);
            case TVN_SELCHANGING:
                return TRUE;
            case HDN_ENDTRACK:
                SendMessage(ptr->hwndTree, TCF_SETDIVIDER, 0, n->pitem->cxy);
                InvalidateRect(ptr->hwndTree, 0, 1);
                return 0;
            case TVN_GETDISPINFO:
                t = (LPNMTVDISPINFO)n;
                if (TreeView_GetItemRect(ptr->hwndTree, t->item.hItem, &r, TRUE)
                    )
                {
                    if (ptr->displaycount < DISPLAY_MAX)
                        ptr->displaylist[ptr->displaycount++] = t->item.hItem;
                    strcpy(t->item.pszText, "");
//                    t->item.cchTextMax = 0;
                }
                return 0;
            case TVN_DELETEITEM:
                ntv = (NM_TREEVIEW*)lParam;
                if (ptr->displaycount)
                    for (i = 0; i < ptr->displaycount; i++)
                if (ptr->displaylist[i] == ntv->itemOld.hItem)
                {
                    ptr->sel =  - 1;
                    memcpy(&ptr->displaylist[i], &ptr->displaylist[i + 1], (ptr
                        ->displaycount - i - 1) *sizeof(HTREEITEM));
                    ptr->displaycount--;
                    return 0;
                }
                return 0;
            }
            // fall through 
        case WM_COMMAND:
            return SendMessage(GetParent(hwnd), iMessage, wParam, lParam);
        case WM_CREATE:
            ptr = (COLUMNINFO*)calloc(1, sizeof(COLUMNINFO)
                );
            ptr->displaycount = 0;
            ptr->sel =  - 1;
            SetWindowLong(hwnd, 0, (int)ptr);
            GetClientRect(hwnd, &r);
            ptr->hwndHeader = CreateWindow(WC_HEADER, 0, WS_CLIPSIBLINGS |
                WS_CHILD | HDS_HORZ | WS_BORDER, r.left, r.top, r.right -
                r.left, r.bottom - r.top, hwnd, 0, (HINSTANCE)GetWindowLong
                (GetParent(hwnd), GWL_HINSTANCE), 0);
            hdl.prc = &r;
            hdl.pwpos = &wp;
            SendMessage(ptr->hwndHeader, HDM_LAYOUT, 0, (LPARAM) &hdl);
            //         wp.x += 2*GetSystemMetrics(SM_CXDLGFRAME );
            //         wp.cx -= 4 * GetSystemMetrics(SM_CXDLGFRAME) ;
            //         wp.y += 2*GetSystemMetrics(SM_CYDLGFRAME );
            //         wp.cy -= 4 * GetSystemMetrics(SM_CYDLGFRAME) ;
            ptr->watchFont = CreateFontIndirect(&systemDialogFont);
            SendMessage(ptr->hwndHeader, WM_SETFONT, (WPARAM)ptr->watchFont, 0);
            SetWindowPos(ptr->hwndHeader, wp.hwndInsertAfter, wp.x, wp.y, wp.cx,
                wp.cy, wp.flags | SWP_SHOWWINDOW);
            r.left = wp.x;
            r.right = wp.x + wp.cx;
            r.top = wp.y + wp.cy;
            ptr->hwndTree = CreateWindowEx(0, szextTreeWindClassName, 0,
                WS_CLIPSIBLINGS | WS_VISIBLE | WS_CHILD | WS_BORDER |
                TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS, r.left, r.top,
                r.right - r.left, r.bottom - r.top, hwnd, (HMENU)1000, 
                (HINSTANCE)GetWindowLong(GetParent(hwnd), GWL_HINSTANCE), 0);
            SendMessage(ptr->hwndTree, WM_SETFONT, (WPARAM)ptr->watchFont, 0);
            hie.mask = HDI_WIDTH;
            SendMessage(ptr->hwndHeader, HDM_GETITEM, 0, (LPARAM) &hie);
            SendMessage(ptr->hwndTree, TCF_SETDIVIDER, 0, hie.cxy);
            break;

        case WM_DESTROY:
            ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
            DestroyWindow(ptr->hwndHeader);
            DeleteObject(ptr->watchFont);
            free((void*)ptr);
            break;
        case WM_LBUTTONDOWN:
        case WM_RBUTTONDOWN:
            break;
        case WM_SIZE:
            ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
            r.left = r.top = 0;
            r.right = LOWORD(lParam);
            r.bottom = HIWORD(lParam);
            hdl.prc = &r;
            hdl.pwpos = &wp;
            SendMessage(ptr->hwndHeader, HDM_LAYOUT, 0, (LPARAM) &hdl);
            //         wp.x += 2*GetSystemMetrics(SM_CXDLGFRAME );
            //         wp.cx -= 4 * GetSystemMetrics(SM_CXDLGFRAME) ;
            //         wp.y += 2*GetSystemMetrics(SM_CYDLGFRAME );
            //         wp.cy -= 4 * GetSystemMetrics(SM_CYDLGFRAME) ;
            SetWindowPos(ptr->hwndHeader, wp.hwndInsertAfter, wp.x, wp.y, wp.cx,
                wp.cy, wp.flags);
            r.left = wp.x;
            r.right = wp.x + wp.cx;
            r.top = wp.y + wp.cy;
            MoveWindow(ptr->hwndTree, r.left, r.top, r.right - r.left, r.bottom
                - r.top, 0);
            GetClientRect(ptr->hwndHeader, &r);
            hie.mask = HDI_WIDTH;
            hie.cxy = (r.right - r.left) / 2;
            SendMessage(ptr->hwndHeader, HDM_SETITEM, 0, (LPARAM) &hie);
            SendMessage(ptr->hwndHeader, HDM_SETITEM, 1, (LPARAM) &hie);
            SendMessage(ptr->hwndTree, TCF_SETDIVIDER, 0, hie.cxy);
            InvalidateRect(ptr->hwndHeader, 0, 1);
            InvalidateRect(ptr->hwndTree, 0, 1);
            break;
        case TCF_SETHEADER:
            ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
            h = (TCHeader*)lParam;
            GetWindowRect(ptr->hwndHeader, &r);
            hie.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
            if (h->colBmp1)
                    hie.mask |= HDI_BITMAP;
            hie.pszText = h->colText1;
            hie.hbm = h->colBmp1;
            hie.cxy = (r.right - r.left) / 2;
            hie.cchTextMax = strlen(h->colText1);
            hie.fmt = HDF_LEFT | HDF_STRING;
            SendMessage(ptr->hwndHeader, HDM_INSERTITEM, 100, (LPARAM) &hie);
            hie.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
            if (h->colBmp2)
                hie.mask |= HDI_BITMAP;
            hie.pszText = h->colText2;
            hie.hbm = h->colBmp2;
            hie.cxy = (r.right - r.left) / 2;
            hie.cchTextMax = strlen(h->colText2);
            hie.fmt = HDF_LEFT | HDF_STRING;
            SendMessage(ptr->hwndHeader, HDM_INSERTITEM, 100, (LPARAM) &hie);
            SendMessage(ptr->hwndTree, TCF_SETDIVIDER, 0, hie.cxy);
            return 0;
        case WM_PAINT:
            dc = BeginPaint(hwnd, &ps);
            EndPaint(hwnd, &ps);
            break;
        case WM_ACTIVATEME:
            SendMessage(GetParent(hwnd), WM_ACTIVATEME, 0, 0);
            break;
        case WM_SETFONT:
        case WM_GETFONT:
            ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
            return SendMessage(ptr->hwndTree, iMessage, wParam, lParam);
        case TCN_PAINT:
            rp = (RECT*)lParam;
            ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
            {
                hie.mask = HDI_WIDTH;
                SendMessage(ptr->hwndHeader, HDM_GETITEM, 0, (LPARAM) &hie);
                hie.cxy -= GetSystemMetrics(SM_CXBORDER);
                rp->left = hie.cxy;
                if (rp->left < rp->right)
                {
                    LOGBRUSH lbrush;
                    HBRUSH graybrush;
                    HDC dc = (HDC)wParam;
                    int lined = FALSE;
                    HFONT font = (HFONT)SendMessage(ptr->hwndTree, WM_GETFONT,
                        0, 0);
                    lbrush.lbStyle = BS_SOLID;
                    lbrush.lbColor = 0xff0000;
                    graybrush = CreateBrushIndirect(&lbrush);
//                    dc = GetDC(ptr->hwndTree);
                    font = SelectObject(dc, font);
                    if (GetWindowLong(hwnd, GWL_STYLE) &TCS_LINE)
                    {
                        HPEN pen;
                        pen = CreatePen(PS_SOLID, 1, 0);

                        lined = TRUE;
                        pen = SelectObject(dc, pen);
                        MoveToEx(dc, rp->left, rp->top, 0);
                        LineTo(dc, rp->left, rp->bottom + 1);
                        pen = SelectObject(dc, pen);
                        DeleteObject(pen);
                    }
                    for (i = 0; i < ptr->displaycount; i++)
                    {
                        COLORREF color, bgcolor;
                        item.hItem = ptr->displaylist[i];
                        item.mask = TVIF_PARAM;
                        TreeView_GetItem(ptr->hwndTree, &item);
                        td = (TCData*)item.lParam;
                        TreeView_GetItemRect(ptr->hwndTree, ptr->displaylist[i],
                            &r, TRUE);
                        if (td->col1Text)
                        {
                            HRGN rgn;
                            rgn = CreateRectRgn(r.left, r.top, rp->left - 2,
                                r.bottom);
                            SelectClipRgn(dc, rgn);
                            if (ptr->sel == i)
                            {
                                color = SetTextColor(dc, RetrieveSysColor(COLOR_WINDOW));
                                bgcolor = SetBkColor(dc, td->col1Color);
                            }
                            else
                                color = SetTextColor(dc, td->col1Color);
                            TextOut(dc, r.left, r.top, td->col1Text, strlen(td
                                ->col1Text));
                            SetTextColor(dc, color);
                            if (ptr->sel == i)
                                SetBkColor(dc, bgcolor);
                            SelectClipRgn(dc, NULL);
                            DeleteObject(rgn);
                        }
                        if (td->col2Text)
                        {
                            if (ptr->sel == i)
                            {
                                color = SetTextColor(dc, RetrieveSysColor(COLOR_WINDOW));
                                bgcolor = SetBkColor(dc, td->col2Color);
                            }
                            else
                                color = SetTextColor(dc, td->col2Color);
                            TextOut(dc, rp->left + (lined ? 3 : 0), r.top, td
                                ->col2Text, strlen(td->col2Text));
                            SetTextColor(dc, color);
                            if (ptr->sel == i)
                                SetBkColor(dc, bgcolor);
                        }
                    }
                    SelectObject(dc, font);
//                    ReleaseDC(ptr->hwndTree, dc);
                    DeleteObject(graybrush);

                }
                ptr->displaycount = 0;
            }
            break;
    }
    return DefWindowProc(hwnd, iMessage, wParam, lParam);
}
Example #30
0
LRESULT album_list_window::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{

	switch (msg)
	{
	case WM_CREATE:
	{
		list_wnd.add_item(this);

		initialised = true;

		modeless_dialog_manager::g_add(wnd);

		create_tree();
		create_filter();

		if (cfg_populate) refresh_tree();

		static_api_ptr_t<library_manager_v3>()->register_callback(this);
	}
	break;
	/*case WM_GETMINMAXINFO:
	{
	LPMINMAXINFO mmi = LPMINMAXINFO(lp);
	mmi->ptMinTrackSize.y = cfg_height;
	return 0;
	}*/
	case WM_SIZE:
		on_size(LOWORD(lp), HIWORD(lp));
		break;
		/*	case DM_GETDEFID:
		return (DC_HASDEFID<<16|IDOK);
		case WM_GETDLGCODE:
		return DLGC_DEFPUSHBUTTON;*/
		//		break;
	case WM_TIMER:
		if (wp == EDIT_TIMER_ID)
		{
			refresh_tree();
			KillTimer(wnd, wp);
			m_timer = false;
		}
		break;
	case WM_COMMAND:
		switch (wp)
		{
		case IDC_FILTER | (EN_CHANGE << 16) :
			if (m_timer)
				KillTimer(wnd_edit, 500);
			m_timer = SetTimer(wnd, EDIT_TIMER_ID, 500, NULL) != 0;
			return TRUE;
		case IDOK:
			if (GetKeyState(VK_SHIFT) & KF_UP) do_playlist(p_selection, false);
			else if (GetKeyState(VK_CONTROL) & KF_UP) do_playlist(p_selection, true, true);
			else do_playlist(p_selection, true);
			return 0;
		}
		break;
	case WM_CONTEXTMENU:
	{
		enum { ID_SEND = 1, ID_ADD, ID_NEW, ID_AUTOSEND, ID_REMOVE, ID_REMOVEDEAD, ID_REFRESH, ID_FILT, ID_CONF, ID_VIEW_BASE };

		HMENU menu = CreatePopupMenu();

		POINT pt = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
		service_ptr_t<contextmenu_manager> p_menu_manager;

		unsigned IDM_MANAGER_BASE = 0;

		HWND list = wnd_tv;

		HTREEITEM treeitem = NULL;

		TVHITTESTINFO ti;
		memset(&ti, 0, sizeof(ti));

		if (pt.x != -1 && pt.y != -1)
		{
			ti.pt = pt;
			ScreenToClient(list, &ti.pt);
			uSendMessage(list, TVM_HITTEST, 0, (long)&ti);
			if (ti.hItem && (ti.flags & TVHT_ONITEM))
			{
				//FIX THIS AND AUTOSEND
				//TreeView_Select(list, ti.hItem, TVGN_DROPHILITE);
				//uSendMessage(list,TVM_SELECTITEM,TVGN_DROPHILITE,(long)ti.hItem);
				treeitem = ti.hItem;
			}
		}
		else
		{
			treeitem = TreeView_GetSelection(list);
			RECT rc;
			if (treeitem && TreeView_GetItemRect(wnd_tv, treeitem, &rc, TRUE))
			{
				MapWindowPoints(wnd_tv, HWND_DESKTOP, (LPPOINT)&rc, 2);

				pt.x = rc.left;
				pt.y = rc.top + (rc.bottom - rc.top) / 2;

			}
			else
			{
				GetMessagePos(&pt);
			}
		}

		TreeView_Select(list, treeitem, TVGN_DROPHILITE);

		HMENU menu_view = CreatePopupMenu();
		unsigned n, m = cfg_view_list.get_count();
		string8_fastalloc temp;
		temp.prealloc(32);

		uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(directory_structure_view_name, view) ? MF_CHECKED : 0), ID_VIEW_BASE + 0, directory_structure_view_name);

		list_t<string_simple, pfc::alloc_fast> views;

		views.add_item(string_simple(directory_structure_view_name));

		for (n = 0; n<m; n++)
		{
			temp = cfg_view_list.get_name(n);
			string_simple item(temp.get_ptr());

			if (item)
			{
				uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(temp, view) ? MF_CHECKED : 0), ID_VIEW_BASE + views.add_item(item), temp);
			}

		}


		IDM_MANAGER_BASE = ID_VIEW_BASE + views.get_count();

		uAppendMenu(menu, MF_STRING | MF_POPUP, (UINT)menu_view, "View");

		if (!m_populated && !cfg_populate)
			uAppendMenu(menu, MF_STRING, ID_REFRESH, "Populate");
		uAppendMenu(menu, MF_STRING | (m_filter ? MF_CHECKED : 0), ID_FILT, "Filter");
		uAppendMenu(menu, MF_STRING, ID_CONF, "Settings");

		bool show_shortcuts = standard_config_objects::query_show_keyboard_shortcuts_in_menus();

		node * p_node = NULL;
		TVITEMEX tvi;
		memset(&tvi, 0, sizeof(tvi));
		tvi.hItem = treeitem;
		tvi.mask = TVIF_HANDLE | TVIF_PARAM;
		TreeView_GetItem(list, &tvi);
		p_node = (node*)tvi.lParam;

		if (treeitem && p_node)
		{
			uAppendMenu(menu, MF_SEPARATOR, 0, "");
			uAppendMenu(menu, MF_STRING, ID_SEND, (show_shortcuts ? "&Send to playlist\tEnter" : "&Send to playlist"));
			uAppendMenu(menu, MF_STRING, ID_ADD, show_shortcuts ? "&Add to playlist\tShift+Enter" : "&Add to playlist");
			uAppendMenu(menu, MF_STRING, ID_NEW, show_shortcuts ? "Send to &new playlist\tCtrl+Enter" : "Send to &new playlist");
			uAppendMenu(menu, MF_STRING, ID_AUTOSEND, "Send to &autosend playlist");

			if (!static_api_ptr_t<core_version_info_v2>()->test_version(0, 9, 6, 0))
			{
				uAppendMenu(menu, MF_STRING, ID_REMOVE, "&Remove from library");
				uAppendMenu(menu, MF_STRING, ID_REMOVEDEAD, "Remove &dead entries (slow)");
			}
			uAppendMenu(menu, MF_SEPARATOR, 0, "");

			contextmenu_manager::g_create(p_menu_manager);
			p_node->sort_entries();

			if (p_menu_manager.is_valid())
			{
				p_menu_manager->init_context(p_node->get_entries(), 0);

				p_menu_manager->win32_build_menu(menu, IDM_MANAGER_BASE, -1);
				menu_helpers::win32_auto_mnemonics(menu);
			}
		}

		int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, get_wnd(), 0);
		DestroyMenu(menu);

		TreeView_Select(list, NULL, TVGN_DROPHILITE);

		if (cmd)
		{
			if (p_menu_manager.is_valid() && (unsigned)cmd >= IDM_MANAGER_BASE)
			{
				p_menu_manager->execute_by_id(cmd - IDM_MANAGER_BASE);
			}
			else if (cmd >= ID_VIEW_BASE)
			{
				unsigned n = cmd - ID_VIEW_BASE;
				if (n<views.get_count())
				{
					view = views[n].get_ptr();
					refresh_tree();
				}
			}
			else if (cmd<ID_VIEW_BASE)
			{
				unsigned cmd2 = 0;
				switch (cmd)
				{
				case ID_NEW:
					do_playlist(p_node, true, true);
					break;
				case ID_SEND:
					do_playlist(p_node, true);
					break;
				case ID_ADD:
					do_playlist(p_node, false);
					break;
				case ID_AUTOSEND:
					do_autosend_playlist(p_node, view, true);
					break;
				case ID_CONF:
				{
					static_api_ptr_t<ui_control>()->show_preferences(g_guid_preferences_album_list_panel);
				}
				break;
				case ID_FILT:
				{
					m_filter = !m_filter;
					create_or_destroy_filter();
				}
				break;
				case ID_REMOVE:
					p_node->remove_from_db();
					break;
				case ID_REMOVEDEAD:
					p_node->remove_dead();
					break;
				case ID_REFRESH:
					if (!m_populated && !cfg_populate)
						refresh_tree();
					break;
				}
				if (cmd2) uSendMessage(get_wnd(), WM_COMMAND, cmd2, 0);
			}
		}

		p_menu_manager.release();

		/*			if (treeitem_context && (treeitem_context != treeitem) && cfg_autosend)
		TreeView_SelectItem(wnd_tv,treeitem);*/


	}
	return 0;
	case WM_NOTIFY:
	{
		LPNMHDR hdr = (LPNMHDR)lp;

		switch (hdr->idFrom)
		{

		case IDC_TREE:
		{
			if (hdr->code == TVN_ITEMEXPANDING)
			{
				LPNMTREEVIEW param = (LPNMTREEVIEW)hdr;
				if (cfg_picmixer && (param->action == TVE_EXPAND))
				{
					TreeView_CollapseOtherNodes(param->hdr.hwndFrom, param->itemNew.hItem);
				}
			}

			else if (hdr->code == TVN_SELCHANGED)
			{
				LPNMTREEVIEW param = (LPNMTREEVIEW)hdr;

				p_selection = (node*)param->itemNew.lParam;
				if ((param->action == TVC_BYMOUSE || param->action == TVC_BYKEYBOARD))
				{
					if (cfg_autosend)
						do_autosend_playlist(p_selection, view);
				}
				if (m_selection_holder.is_valid())
				{
					m_selection_holder->set_selection(p_selection.is_valid() ? p_selection->get_entries() : metadb_handle_list());
				}
#if 0
				if (cfg_picmixer)
				{
					HTREEITEM ti_parent_old = TreeView_GetParent(param->hdr.hwndFrom, param->itemOld.hItem);
					HTREEITEM ti_parent_new = TreeView_GetParent(param->hdr.hwndFrom, param->itemNew.hItem);

					if (/*ti_parent_old != param->itemNew.hItem &&  */!TreeView_IsChild(param->hdr.hwndFrom, param->itemNew.hItem, param->itemOld.hItem))
					{
						HTREEITEM ti = //TreeView_GetLevel(param->hdr.hwndFrom, param->itemNew.hItem) < TreeView_GetLevel(param->hdr.hwndFrom, param->itemOld.hItem) ? 
							TreeView_GetCommonParentChild(param->hdr.hwndFrom, param->itemOld.hItem, param->itemNew.hItem)
							//: param->itemOld.hItem
							;
						if (ti && ti != TVI_ROOT) TreeView_Expand(param->hdr.hwndFrom, ti, TVE_COLLAPSE);
					}

					if (ti_parent_new)
					{

						HTREEITEM child = TreeView_GetChild(param->hdr.hwndFrom, ti_parent_new);
						while (child)
						{
							if (child != param->itemNew.hItem)
							{

							}
						}
					}
				}
#endif
			}
		}
		break;
		}

	}
	break;
	case WM_DESTROY:
		static_api_ptr_t<library_manager_v3>()->unregister_callback(this);
		modeless_dialog_manager::g_remove(wnd);
		destroy_tree();
		destroy_filter();
		m_selection_holder.release();
		m_root.release();
		p_selection.release();
		if (initialised)
		{
			list_wnd.remove_item(this);
			if (list_wnd.get_count() == 0)
			{
				DeleteFont(g_font);
				g_font = 0;
			}
			initialised = false;
		}
		break;
	}
	return DefWindowProc(wnd, msg, wp, lp);
}