static void Main_OnMouseMove(HWND hwndParent, HWND hwndTV, LONG xCur, LONG yCur) { HTREEITEM htiTarget; // handle to target item TVHITTESTINFO tvht; // hit test information //POINT Pos; INT iIndex; struct OBJ *poj; // xCur,yCur sono della parent // Drag the item to the current position of the mouse cursor. // Muove l'immagine del Drag nella posizione del cursore iIndex=TVFind(TV_FINDHWND,hwndTV); poj=TVList[iIndex].lpObj; xCur-=poj->px; yCur-=poj->py; //GetCursorPos(&Pos); //ImageList_DragMove(Pos.x,Pos.y); ImageList_DragMove(xCur+12,yCur+12); // Find out if the cursor is on the item. If it is, highlight // the item as a drop target. ZeroFill(tvht); tvht.pt.x=xCur; tvht.pt.y=yCur; tvht.flags=TVHT_ONITEM|TVHT_ONITEMLABEL; if ((hDropItem = htiTarget = TreeView_HitTest(hwndTV, &tvht)) != NULL) { ImageList_DragShowNolock(FALSE); TreeView_SelectDropTarget(hwndTV, htiTarget); //hDropItem=htiTarget; ImageList_DragShowNolock(TRUE); } return; }
int sTree::AddChild(char* text){ tvinsert.hParent=Parent; tvinsert.hInsertAfter=TVI_LAST; // work as root level tvinsert.item.pszText=text; Parent=(HTREEITEM)SendMessage(hTree,TVM_INSERTITEM,0,(LPARAM)&tvinsert); TreeView_SelectDropTarget(hTree,Parent); return 0; }
static void CursorAutoSelect(INT xCur,INT yCur,INT iTVIndex)//HWND hwndTV,struct OBJ *poj) { HTREEITEM htiTarget; // handle to target item TVHITTESTINFO tvht; // hit test information //xCur-=TVList[iTVIndex].lpObj->px; //yCur-=TVList[iTVIndex].lpObj->py; ZeroFill(tvht); tvht.pt.x=xCur; tvht.pt.y=yCur; tvht.flags=TVHT_ONITEM|TVHT_ONITEMLABEL; if ((htiTarget = TreeView_HitTest(TVList[iTVIndex].hWndList, &tvht)) != NULL) { TreeView_SelectDropTarget(TVList[iTVIndex].hWndList, htiTarget); TreeView_SelectItem(TVList[iTVIndex].hWndList,htiTarget); } }
bool SetDropTarget(_Ty Key) { bool r = false; HTREEITEM hItem = KeyToHandle(Key); if (NULL != hItem) { if (TRUE == TreeView_SelectDropTarget(m_hWnd, hItem)) { r = true; } } return r; }
void CTaskListDropTarget::OnDragLeave(CWnd* pWnd) { if (IS_WND_TYPE(pWnd, CTreeCtrl, WC_TREEVIEW)) { TreeView_SelectDropTarget(pWnd->GetSafeHwnd(), NULL); } else if (IS_WND_TYPE(pWnd, CListCtrl, WC_LISTVIEW)) { if (m_nLVPrevHilite != -1) // shouldn't happen { ListView_SetItemState(pWnd->GetSafeHwnd(), m_nLVPrevHilite, 0, LVIS_DROPHILITED); // all items } m_nLVPrevHilite = -1; } }
DROPEFFECT CTaskListDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* /*pObject*/, DWORD /*dwKeyState*/, CPoint /*point*/) { if (IS_WND_TYPE(pWnd, CTreeCtrl, WC_TREEVIEW)) { TreeView_SelectDropTarget(pWnd->GetSafeHwnd(), NULL); } else if (IS_WND_TYPE(pWnd, CListCtrl, WC_LISTVIEW)) { if (m_nLVPrevHilite != -1) // shouldn't happen { ListView_SetItemState(pWnd->GetSafeHwnd(), m_nLVPrevHilite, 0, LVIS_DROPHILITED); // all items } m_nLVPrevHilite = -1; } return DROPEFFECT_NONE; }
static LRESULT TreeViewNotify(HWND hWnd, LPARAM lParam,INT iLVIndex,LPNMHDR pnmh) { LPNMLVKEYDOWN pnkd; struct OBJ *poj; CHAR szServ[20]; LPNMHDR lpnmh; HTREEITEM hItem; LPNMTREEVIEW lpnmtv; TVITEM item; BOOL fReturn; LRESULT lRes; if (iLVIndex>100||iLVIndex<0) return 0; poj=TVList[iLVIndex].lpObj; if (pnmh->code==0) efx2(); lpnmh = (LPNMHDR) lParam; // Lancio se connessa la procedura di controllo esterna if (TVList[iLVIndex].subPostNotify) { fReturn=FALSE; lRes=(*TVList[iLVIndex].subPostNotify)(poj,&fReturn, EXT_PREV,hWnd,0,0,lParam); if (fReturn) return lRes; } switch(pnmh->code) { case TVN_SELCHANGING: lpnmtv = (LPNMTREEVIEW) lParam; TreeView_SelectDropTarget(lpnmh->hwndFrom,lpnmtv->itemNew.hItem); ZeroFill(item); hItem=TreeView_GetSelection(lpnmh->hwndFrom); item.mask=TVIF_PARAM; item.hItem=hItem; item.pszText=szServ; item.cchTextMax=sizeof(szServ); TreeView_GetItem(lpnmh->hwndFrom,&item); OBJ_key=item.lParam; sprintf(szServ,"%sSEL",poj->nome); obj_addevent(szServ); break; case NM_DBLCLK : ZeroFill(item); hItem=TreeView_GetSelection(lpnmh->hwndFrom); item.mask=TVIF_PARAM; item.hItem=hItem; item.pszText=szServ; item.cchTextMax=sizeof(szServ); TreeView_GetItem(lpnmh->hwndFrom,&item); OBJ_key=item.lParam; sprintf(szServ,"%sDCLK",poj->nome); obj_addevent(szServ); break; case NM_RCLICK: hItem=TreeView_GetSelection(lpnmh->hwndFrom); if (hItem==NULL) break; //memset(&item,0,sizeof(item)); ZeroFill(item); item.mask=TVIF_TEXT|TVIF_PARAM; item.hItem=hItem; item.pszText=szServ; item.cchTextMax=sizeof(szServ); TreeView_GetItem(lpnmh->hwndFrom,&item); //_d_("[%s] ",szServ); OBJ_key=item.lParam; sprintf(szServ,"%sRC",poj->nome); obj_addevent(szServ); break; case TVN_BEGINDRAG: //case TVN_BEGINRDRAG: Main_OnBeginDrag(lpnmh->hwndFrom, (LPNMTREEVIEW) lParam); break; //efx1(); //break; case TVN_KEYDOWN: pnkd = (LPNMLVKEYDOWN) lParam; if (pnkd->wVKey==ESC) winSetFocus(WindowNow()); if ((pnkd->wVKey>=' ')&&(pnkd->wVKey<='<')) { //efx1(); } break; } // Lancio se connessa la procedura di controllo esterna if (TVList[iLVIndex].subPostNotify) { fReturn=FALSE; lRes=(*TVList[iLVIndex].subPostNotify)(poj,&fReturn, EXT_AFTER,hWnd,0,0,lParam); // (TVSUB_POST,poj,hWnd,lParam,pnmh,&fReturn); if (fReturn) return lRes; } return 0; }
LRESULT CALLBACK ProjectProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { int i; RECT rs; NM_TREEVIEW *nm; DWINFO info; LPNMTVKEYDOWN key; PROJECTITEM *data; TVHITTESTINFO hittest; HWND win; HTREEITEM oldSel; static HCURSOR origCurs; static BOOL dragging; static BOOL inView; static HTREEITEM srcItem, dstItem; switch (iMessage) { LOGFONT lf; case WM_SYSCOMMAND: if (wParam == SC_CLOSE) SendMessage(hwnd, WM_CLOSE, 0, 0); break; // case WM_SETTEXT: // return SendMessage(hwndTab, iMessage, wParam, lParam); case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: SetFocus(hwnd); break; case WM_NOTIFY: nm = (NM_TREEVIEW*)lParam; switch (nm->hdr.code) { case NM_CUSTOMDRAW: return CustomDraw(hwnd, (LPNMTVCUSTOMDRAW)nm); case N_EDITDONE: DoneRenaming(); break; case TVN_BEGINDRAG: GetCursorPos(&hittest.pt); ScreenToClient(prjTreeWindow, &hittest.pt); srcItem = TreeView_HitTest(prjTreeWindow, &hittest); data = GetItemInfo(srcItem); if (data && (data->type == PJ_FILE || data->type == PJ_FOLDER)) { dragging = TRUE; SetCapture(hwnd); origCurs = SetCursor(dragCur); inView = TRUE; } break; case TVN_KEYDOWN: key = (LPNMTVKEYDOWN)lParam; switch (key->wVKey) { case VK_INSERT: if (GetKeyState(VK_CONTROL) &0x80000000) { data = GetItemInfo(prjSelectedItem); if (data) { int msg = -1; switch (data->type) { case PJ_WS: msg = IDM_EXISTINGPROJECT; break; case PJ_PROJ: msg = IDM_NEWFOLDER; break; case PJ_FOLDER: msg = IDM_EXISTINGFILE; break; } if (msg != -1) PostMessage(hwnd, WM_COMMAND, msg, 0); } } else if (GetKeyState(VK_SHIFT) &0x80000000) { data = GetItemInfo(prjSelectedItem); if (data) { int msg = -1; switch (data->type) { case PJ_WS: msg = IDM_NEWPROJECT; break; case PJ_PROJ: msg = IDM_NEWFOLDER; break; case PJ_FOLDER: msg = IDM_NEWFILE_P; break; } if (msg != -1) PostMessage(hwnd, WM_COMMAND, msg, 0); } } else { data = GetItemInfo(prjSelectedItem); if (data && (data->type != PJ_WS)) PostMessage(hwnd, WM_COMMAND, IDM_RENAME, 0); } break; case VK_DELETE: if (!(GetKeyState(VK_CONTROL) &0x80000000) && !(GetKeyState(VK_SHIFT) &0x8000000)) { data = GetItemInfo(prjSelectedItem); if (data && (data->type == PJ_FOLDER || data->type == PJ_FILE)) PostMessage(hwnd, WM_COMMAND, IDM_REMOVE, 0); } break; case VK_RETURN: SendMessage(hwnd, WM_COMMAND, IDM_OPENFILES, 0); break; } break; case NM_DBLCLK: oldSel = prjSelectedItem; GetCursorPos(&hittest.pt); ScreenToClient(prjTreeWindow, &hittest.pt); prjSelectedItem = TreeView_HitTest(prjTreeWindow, &hittest); if (prjSelectedItem) PostMessage(hwnd, WM_COMMAND, IDM_OPENFILES, 0); prjSelectedItem = oldSel; return 0; case NM_RCLICK: GetCursorPos(&hittest.pt); ScreenToClient(prjTreeWindow, &hittest.pt); prjSelectedItem = TreeView_HitTest(prjTreeWindow, &hittest); if (prjSelectedItem) { TreeView_SelectItem(prjTreeWindow, prjSelectedItem); } CreateProjectMenu(); break; case TVN_SELCHANGED: nm = (NM_TREEVIEW*)lParam; prjSelectedItem = nm->itemNew.hItem; if (prjSelectedItem == 0) prjSelectedItem = workArea->hTreeItem; break; case TVN_ITEMEXPANDED: nm = (NM_TREEVIEW *)lParam; data = GetItemInfo(nm->itemNew.hItem); if (data) { if (data->type == PJ_FOLDER) { TV_ITEM setitem; memset(&setitem, 0, sizeof(setitem)); setitem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; setitem.iImage = setitem.iSelectedImage = nm->action == TVE_EXPAND ? ilfolderOpen : ilfolderClose; setitem.hItem = nm->itemNew.hItem; TreeView_SetItem(prjTreeWindow, &setitem); } if (nm->action == TVE_EXPAND) { data->expanded = TRUE; } else data->expanded = FALSE; return 0; } break; case TVN_DELETEITEM: nm = (NM_TREEVIEW *)lParam; if (nm->itemOld.hItem == prjSelectedItem) prjSelectedItem = TreeView_GetSelection(prjTreeWindow); break; } break; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_TBPROFILE: if (HIWORD(wParam) == CBN_SELENDOK) { int i = SendMessage(hwndTbProfile, CB_GETCURSEL, 0 , 0); if (i != CB_ERR) { if (i == 0) { strcpy(currentProfileName, sysProfileName); } else { PROFILENAMELIST *pf = profileNames; while (pf && --i) pf = pf->next; if (pf) { strcpy(currentProfileName, pf->name); } } MarkChanged(workArea, TRUE); } } break; case ID_TBBUILDTYPE: if (HIWORD(wParam) == CBN_SELENDOK) { int i = SendMessage(hwndTbBuildType, CB_GETCURSEL, 0 , 0); if (i != CB_ERR) { profileDebugMode = i == 0 ? 1 : 0; MarkChanged(workArea, TRUE); } } break; case IDM_RESETPROFILECOMBOS: { HWND htemp; PROFILENAMELIST *pf; int selected,n; int count; POINT pt; pf = profileNames; selected = 0; count = 0; SendMessage(hwndTbProfile, CB_RESETCONTENT, 0, 0); SendMessage(hwndTbProfile, CB_ADDSTRING, 0, (LPARAM)sysProfileName); while (pf) { count++; if (!strcmp(pf->name,currentProfileName)) selected = count; SendMessage(hwndTbProfile, CB_ADDSTRING, 0, (LPARAM)pf->name); pf = pf->next; } SendMessage(hwndTbProfile, CB_SETCURSEL, selected, 0); SendMessage(hwndTbBuildType, CB_RESETCONTENT, 0, 0); SendMessage(hwndTbBuildType, CB_ADDSTRING, 0, (LPARAM)"Debug"); SendMessage(hwndTbBuildType, CB_ADDSTRING, 0, (LPARAM)"Release"); SendMessage(hwndTbBuildType, CB_SETCURSEL, profileDebugMode ? 0 : 1, 0); pt.x = 5; pt.y = 5; htemp = ChildWindowFromPoint(hwndTbProfile, pt); SendMessage(htemp, EM_SETREADONLY, 1, 0); htemp = ChildWindowFromPoint(hwndTbBuildType, pt); SendMessage(htemp, EM_SETREADONLY, 1, 0); EnableWindow(hwndTbProfile, TRUE); EnableWindow(hwndTbBuildType, TRUE); break; } case IDM_IMPORT_CWS: ImportProject(FALSE); break; case IDM_IMPORT_CTG: ImportProject(TRUE); break; case IDM_DOSWINDOW: { DosWindow(activeProject ? activeProject->realName : NULL, NULL, NULL, NULL, NULL); } break; case IDM_MAKEWINDOW: { char exec[MAX_PATH]; sprintf(exec, "%s\\bin\\imake.exe", szInstallPath); DosWindow(activeProject ? activeProject->realName : NULL, exec, "", "Custom Make", "Make Is Complete."); } break; case IDM_RUN: SaveWorkArea(workArea); dbgRebuildMain(wParam); break; case IDM_SETACTIVEPROJECT: ProjectSetActive(); break; case IDM_NEWFILE_P: ProjectNewFile(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_EXISTINGFILE: ProjectExistingFile(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_NEWPROJECT: ProjectNewProject(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_EXISTINGPROJECT: ProjectExistingProject(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break ; case IDM_REMOVE: ProjectRemove(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_RENAME: ProjectRename(); break; case IDM_NEWFOLDER: ProjectNewFolder(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_NEWWS: if (uState != notDebugging) { if (ExtendedMessageBox("WorkArea", MB_OKCANCEL, "This action requires the debugger to be stopped.") != IDOK) { break; } abortDebug(); } SelectWindow(DID_PROJWND); ProjectNewWorkArea(); break; case IDM_OPENWS: if (uState != notDebugging) { if (ExtendedMessageBox("WorkArea", MB_OKCANCEL, "This action requires the debugger to be stopped.") != IDOK) { break; } abortDebug(); } SelectWindow(DID_PROJWND); ProjectExistingWorkArea(); break; case IDM_CLOSEWS: if (making) break; if (uState != notDebugging) { if (ExtendedMessageBox("WorkArea", MB_OKCANCEL, "This action requires the debugger to be stopped.") != IDOK) { break; } abortDebug(); } CloseWorkArea(); break; case IDM_SAVEWS: SaveAllProjects(workArea, TRUE); break; case IDM_COMPILEFILEFROMTREE: { PROJECTITEM *data = GetItemInfo(prjSelectedItem); if (data && data->type == PJ_FILE) { unlink(data->outputName); Maker(data, TRUE); } } break; case IDM_COMPILEFILE: win = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0); if (IsWindow(win) && IsEditWindow(win)) { HTREEITEM item = FindItemByWind(win); PROJECTITEM *data = GetItemInfo(item); if (data) { unlink(data->outputName); Maker(data, TRUE); } } break; case IDM_GENMAKE: if (workArea && workArea->children) { genMakeFile(workArea); } else { ExtendedMessageBox("Makefile Generation", MB_SETFOREGROUND | MB_SYSTEMMODAL, "You need at least one project to generate a make file"); } break; case IDM_MAKE: if (HIWORD(wParam)) if (GetKeyState(VK_CONTROL) &0x80000000) SendMessage(hwnd, WM_COMMAND, IDM_COMPILEFILE, 0); else if (GetKeyState(VK_SHIFT) &0x80000000) Maker(activeProject, FALSE); else Maker(workArea, FALSE); else Maker(workArea, FALSE); break; case IDM_MAKE_RIGHTCLICK: if (HIWORD(wParam)) if (GetKeyState(VK_CONTROL) &0x80000000) SendMessage(hwnd, WM_COMMAND, IDM_COMPILEFILE, 0); else if (GetKeyState(VK_SHIFT) &0x80000000) Maker(activeProject, FALSE); else Maker(workArea, FALSE); else { if (prjSelectedItem) { PROJECTITEM *data = GetItemInfo(prjSelectedItem); if (data) { Maker(data, FALSE); break; } } Maker(workArea, FALSE); } break; case IDM_BUILDALL: Maker(workArea, TRUE); break; case IDM_BUILDALL_RIGHTCLICK: if (prjSelectedItem) { PROJECTITEM *data = GetItemInfo(prjSelectedItem); if (data) { Maker(data, TRUE); break; } } Maker(workArea, TRUE); break; case IDM_BUILDSELECTED: Maker(activeProject, FALSE); break; case IDM_STOPBUILD: StopBuild(); break; case IDM_CALCULATEDEPENDS: CalculateProjectDepends(GetItemInfo(prjSelectedItem)); break; case IDM_RUNNODEBUG: { SaveWorkArea(workArea); RunProgram(activeProject); break; } case IDM_SELECTPROFILE: SelectProfileDialog(); break; case IDM_ACTIVEPROJECTPROPERTIES: if (activeProject) prjSelectedItem = activeProject->hTreeItem; // fall through case IDM_PROJECTPROPERTIES: data = GetItemInfo(prjSelectedItem); ShowBuildProperties(data); break; case IDM_PROJECTDEPENDS: data = GetItemInfo(prjSelectedItem); EditProjectDependencies(data); break; case IDM_OPENFILES: data = GetItemInfo(prjSelectedItem); if (data) if (data->type == PJ_FILE) { if (strlen(data->realName) >= 3 && !stricmp(data->realName + strlen(data->realName) -3, ".rc")) { NavigateToResource(data); } else { strcpy(info.dwName, data->realName); strcpy(info.dwTitle, data->displayName); info.dwLineNo = - 1; info.logMRU = FALSE; info.newFile = FALSE; CreateDrawWindow(&info, TRUE); } } break; case IDM_CLOSE: SendMessage(hwnd, WM_CLOSE, 0, 0); break; default: return DefWindowProc(hwnd, iMessage, wParam, lParam); } break; case WM_LBUTTONUP: if (dragging) { SetCursor(origCurs); ReleaseCapture(); dragging = FALSE; TreeView_SelectDropTarget(prjTreeWindow, NULL); if (inView && dstItem != srcItem && srcItem && dstItem) { DragTo(dstItem, srcItem); } } break; case WM_MOUSEMOVE: if (dragging) { hittest.pt.x = (long)(short)LOWORD(lParam); hittest.pt.y = (long)(short)HIWORD(lParam); dstItem = TreeView_HitTest(prjTreeWindow, &hittest); if (dstItem && dstItem != srcItem) { PROJECTITEM *srcData = GetItemInfo(srcItem); data = GetItemInfo(dstItem); if (srcData && data) { PROJECTITEM *p = data->parent; while (p) if (p == srcData) break; else p = p->parent; if (p) { if (inView) { inView = FALSE; SetCursor(noCur); TreeView_SelectDropTarget(prjTreeWindow, NULL); } break; } } if (data && (data->type == PJ_PROJ || data->type == PJ_FOLDER)) { if (!inView) { inView = TRUE; SetCursor(dragCur); } TreeView_SelectDropTarget(prjTreeWindow, dstItem); } else { if (inView) { inView = FALSE; SetCursor(noCur); TreeView_SelectDropTarget(prjTreeWindow, NULL); } } } else { if (inView) { inView = FALSE; SetCursor(noCur); TreeView_SelectDropTarget(prjTreeWindow, NULL); } } } break; case WM_SETFOCUS: PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); SetFocus(prjTreeWindow); break; case WM_CREATE: hwndProject = hwnd; GetClientRect(hwnd, &rs); treeViewSelected = 0; dragCur = LoadCursor(hInstance, "ID_DRAGCUR"); noCur = LoadCursor(hInstance, "ID_NODRAGCUR"); folderClose = LoadBitmap(hInstance, "ID_FOLDERCLOSE"); folderOpen = LoadBitmap(hInstance, "ID_FOLDEROPEN"); treeIml = ImageList_Create(16, 16, ILC_COLOR24, IL_IMAGECOUNT+2, 0); mainIml = LoadBitmap(hInstance, "ID_FILES"); ChangeBitmapColor(mainIml, 0xffffff, RetrieveSysColor(COLOR_WINDOW)); ImageList_Add(treeIml, mainIml, NULL); ilfolderClose = ImageList_Add(treeIml, folderClose, 0); ilfolderOpen = ImageList_Add(treeIml, folderOpen, 0); DeleteObject(folderClose); DeleteObject(folderOpen); DeleteObject(mainIml); prjTreeWindow = CreateWindowEx(0, sztreeDoubleBufferName, "", WS_VISIBLE | WS_CHILD | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_TRACKSELECT, 0, 0, rs.right, rs.bottom, hwnd, (HMENU)ID_TREEVIEW, hInstance, NULL); TreeView_SetImageList(prjTreeWindow, treeIml, TVSIL_NORMAL); lf = systemDialogFont; projFont = CreateFontIndirect(&lf); lf.lfItalic = TRUE; italicProjFont = CreateFontIndirect(&lf); lf.lfItalic = FALSE; lf.lfWeight = FW_BOLD; boldProjFont = CreateFontIndirect(&lf); SendMessage(prjTreeWindow, WM_SETFONT, (WPARAM)boldProjFont, 0); return 0; case WM_CLOSE: SaveAllProjects(workArea, FALSE); break; case WM_DESTROY: FreeSubTree(workArea, FALSE); DestroyWindow(prjTreeWindow); DeleteObject(projFont); DeleteObject(boldProjFont); DeleteObject(italicProjFont); DestroyCursor(dragCur); DestroyCursor(noCur); hwndProject = 0; break; case WM_SIZE: MoveWindow(prjTreeWindow, 0, 0, LOWORD(lParam), HIWORD(lParam), 0); break; default: break; } return DefWindowProc(hwnd, iMessage, wParam, lParam); }
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); }
static LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { CMsgTree *dat = CWndUserData(hWnd).GetMsgTree(); switch (Msg) { case WM_NOTIFY: if (((LPNMHDR)lParam)->hwndFrom == dat->hTreeView) { switch (((LPNMHDR)lParam)->code) { case TVN_BEGINDRAG: { LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; NMMSGTREE nm = { 0 }; COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); int Order = TreeCtrl->hItemToOrder(pnmtv->itemNew.hItem); _ASSERT(Order != -1); if (Order != -1) { nm.ItemOld = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; nm.hdr.code = MTN_BEGINDRAG; nm.hdr.hwndFrom = dat->hTreeView; nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); if (!SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm)) { SetCapture(hWnd); dat->hPrevDropTarget = dat->hDragItem = pnmtv->itemNew.hItem; SetFocus(dat->hTreeView); TreeView_SelectItem(dat->hTreeView, dat->hDragItem); } } } break; case TVN_SELCHANGED: if (dat->UpdateLock) return 0; else { LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; NMMSGTREE nm = { 0 }; COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); if (pnmtv->itemOld.hItem) { int Order = TreeCtrl->IDToOrder(pnmtv->itemOld.lParam); if (Order != -1) { nm.ItemOld = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; } } if (pnmtv->itemNew.hItem) { int Order = TreeCtrl->IDToOrder(pnmtv->itemNew.lParam); if (Order != -1) { nm.ItemNew = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; } } nm.hdr.code = MTN_SELCHANGED; nm.hdr.hwndFrom = dat->hTreeView; nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm); } break; case TVN_BEGINLABELEDIT: if (dat->GetTreeCtrl()->IDToOrder(((LPNMTVDISPINFO)lParam)->item.lParam) < 0) return true; // cancel editing g_OrigEditProc = (WNDPROC)SetWindowLongPtr(TreeView_GetEditControl(dat->hTreeView), GWLP_WNDPROC, (LONG_PTR)EditSubclassProc); break; case TVN_ENDLABELEDIT: { LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO)lParam; if (ptvdi->item.pszText) { COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); int Order = TreeCtrl->IDToOrder(ptvdi->item.lParam); if (Order >= 0) { TreeCtrl->Value[Order].Title = ptvdi->item.pszText; TreeCtrl->SetModified(true); NMMSGTREE nm = { 0 }; nm.ItemNew = &TreeCtrl->Value[Order]; nm.hdr.code = MTN_ITEMRENAMED; nm.hdr.hwndFrom = dat->hTreeView; nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); SendMessage(GetParent(dat->hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); return true; // commit new text } } } break; case NM_CLICK: case NM_RCLICK: { TVHITTESTINFO hitTest; hitTest.pt.x = (short)LOWORD(GetMessagePos()); hitTest.pt.y = (short)HIWORD(GetMessagePos()); ScreenToClient(dat->hTreeView, &hitTest.pt); TreeView_HitTest(dat->hTreeView, &hitTest); if (hitTest.hItem) { if (TreeView_GetSelection(dat->hTreeView) == hitTest.hItem) // make sure TVN_SELCHANGED notification is sent always, even if previous selected item was the same as new TreeView_SelectItem(dat->hTreeView, NULL); TreeView_SelectItem(dat->hTreeView, hitTest.hItem); } } break; case NM_CUSTOMDRAW: NMTVCUSTOMDRAW *lpNMCD = (NMTVCUSTOMDRAW*)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; TreeView_GetItemRect(lpNMCD->nmcd.hdr.hwndFrom, (HTREEITEM)lpNMCD->nmcd.dwItemSpec, &rc, true); int iSize = GetSystemMetrics(SM_CXSMICON); int x = rc.left - iSize - 5; for (int i = 0; i < _countof(SettingsList); i++) { if (lpNMCD->nmcd.lItemlParam == dat->MsgTreePage.GetValue(SettingsList[i].DBSetting)) { DrawIconEx(lpNMCD->nmcd.hdc, x, rc.top, Skin_LoadProtoIcon(NULL, SettingsList[i].Status), iSize, iSize, 0, GetSysColorBrush(COLOR_WINDOW), DI_NORMAL); x -= iSize + 1; } } } } } break; case WM_MOUSEMOVE: if (dat->hDragItem) { TVHITTESTINFO hti; hti.pt.x = (short)LOWORD(lParam); hti.pt.y = (short)HIWORD(lParam); ClientToScreen(hWnd, &hti.pt); ScreenToClient(dat->hTreeView, &hti.pt); TreeView_HitTest(dat->hTreeView, &hti); if (hti.hItem) { TreeView_SelectDropTarget(dat->hTreeView, hti.hItem); SetTimer(hWnd, MSGTREE_TIMER_ID, MSGTREE_DRAGANDDROP_GROUPEXPANDTIME, NULL); } else { if (hti.flags & TVHT_ABOVE) SendMessage(dat->hTreeView, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0); if (hti.flags & TVHT_BELOW) SendMessage(dat->hTreeView, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0); TreeView_SelectDropTarget(dat->hTreeView, NULL); KillTimer(hWnd, MSGTREE_TIMER_ID); } } break; case WM_LBUTTONUP: if (dat->hDragItem) { TreeView_SelectDropTarget(dat->hTreeView, NULL); KillTimer(hWnd, MSGTREE_TIMER_ID); ReleaseCapture(); TVHITTESTINFO hti; hti.pt.x = (short)LOWORD(lParam); hti.pt.y = (short)HIWORD(lParam); ClientToScreen(hWnd, &hti.pt); ScreenToClient(dat->hTreeView, &hti.pt); TreeView_HitTest(dat->hTreeView, &hti); if (hti.hItem && dat->hDragItem != hti.hItem) { NMMSGTREE nm = { 0 }; COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); int OrderOld = TreeCtrl->hItemToOrder(dat->hDragItem); int OrderNew = TreeCtrl->hItemToOrder(hti.hItem); _ASSERT(OrderOld != -1 && OrderNew != -1); nm.ItemOld = (OrderOld <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(OrderOld)] : (CBaseTreeItem*)&TreeCtrl->Value[OrderOld]; nm.ItemNew = (OrderNew <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(OrderNew)] : (CBaseTreeItem*)&TreeCtrl->Value[OrderNew]; nm.hdr.code = MTN_ENDDRAG; nm.hdr.hwndFrom = dat->hTreeView; nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); if (!SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm)) { dat->UpdateLock++; dat->GetTreeCtrl()->MoveItem(hWnd, dat->hDragItem, hti.hItem); dat->UpdateLock--; } } dat->hDragItem = NULL; } break; case WM_TIMER: if (wParam == MSGTREE_TIMER_ID) { KillTimer(hWnd, MSGTREE_TIMER_ID); TVHITTESTINFO hti; hti.pt.x = (short)LOWORD(GetMessagePos()); hti.pt.y = (short)HIWORD(GetMessagePos()); ScreenToClient(dat->hTreeView, &hti.pt); TreeView_HitTest(dat->hTreeView, &hti); if (hti.hItem && dat->hDragItem != hti.hItem && TreeView_GetChild(dat->hTreeView, hti.hItem)) // target is a group and is not the same item that we're dragging TreeView_Expand(dat->hTreeView, hti.hItem, TVE_EXPAND); } } return CallWindowProc(dat->OrigParentProc, hWnd, Msg, wParam, lParam); }
BOOL CTaskListDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pObject, DROPEFFECT /*dropEffect*/, CPoint point) { CString sFilePath; if (GetDroppedFilePath(pObject, sFilePath)) { CString sClass = CWinClasses::GetClass(*pWnd); m_pParent->SetForegroundWindow(); if (IS_WND_TYPE(pWnd, CTreeCtrl, WC_TREEVIEW)) { TVHITTESTINFO tvhti = { { point.x, point.y }, 0, 0 }; TreeView_HitTest(pWnd->GetSafeHwnd(), &tvhti); TreeView_SelectDropTarget(pWnd->GetSafeHwnd(), NULL); if (tvhti.hItem) { m_pParent->SendMessage(WM_TLDT_DROPFILE, (WPARAM)tvhti.hItem, (LPARAM)(LPCTSTR)sFilePath); } } else if (IS_WND_TYPE(pWnd, CListCtrl, WC_LISTVIEW)) { LVHITTESTINFO lvhti = { { point.x, point.y }, 0 }; ListView_HitTest(pWnd->GetSafeHwnd(), &lvhti); if (m_nLVPrevHilite != -1) { ListView_SetItemState(pWnd->GetSafeHwnd(), m_nLVPrevHilite, 0, LVIS_DROPHILITED); // all items m_nLVPrevHilite = -1; } if (lvhti.iItem != -1) { m_pParent->SendMessage(WM_TLDT_DROPFILE, (WPARAM)lvhti.iItem, (LPARAM)(LPCTSTR)sFilePath); } } else if (IS_WND_TYPE(pWnd, CEdit, WC_EDIT)) { if (!(pWnd->GetStyle() & ES_READONLY)) { m_pParent->SendMessage(WM_TLDT_DROPFILE, (WPARAM)0, (LPARAM)(LPCTSTR)sFilePath); } } else if (pWnd->IsKindOf(RUNTIME_CLASS(CDialog)) || pWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd))) { // allow dropping only on titlebar if ((pWnd->GetStyle() & WS_CAPTION) && point.y < 0) { m_pParent->SendMessage(WM_TLDT_DROPFILE, (WPARAM)0, (LPARAM)(LPCTSTR)sFilePath); } } } else // cleanup { if (IS_WND_TYPE(pWnd, CTreeCtrl, WC_TREEVIEW)) { TreeView_SelectDropTarget(pWnd->GetSafeHwnd(), NULL); } else if (IS_WND_TYPE(pWnd, CListCtrl, WC_LISTVIEW)) { if (m_nLVPrevHilite != -1) { ListView_SetItemState(pWnd->GetSafeHwnd(), m_nLVPrevHilite, 0, LVIS_DROPHILITED); // all items } m_nLVPrevHilite = -1; } } return FALSE; // because we handle it }
DROPEFFECT CTaskListDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pObject, DWORD /*dwKeyState*/, CPoint point) { if (!pWnd->IsWindowEnabled()) { return DROPEFFECT_NONE; } BOOL bFilename = pObject->IsDataAvailable((CLIPFORMAT)::RegisterClipboardFormat(_T("FileName"))); BOOL bFileDrop = pObject->IsDataAvailable(CF_HDROP); if (bFilename || bFileDrop) { if (IS_WND_TYPE(pWnd, CTreeCtrl, WC_TREEVIEW)) { TVHITTESTINFO tvhti = { { point.x, point.y }, 0, 0 }; TreeView_HitTest(pWnd->GetSafeHwnd(), &tvhti); TreeView_SelectDropTarget(pWnd->GetSafeHwnd(), tvhti.hItem); if (tvhti.hItem) { return bFilename ? DROPEFFECT_LINK : DROPEFFECT_COPY; } } else if (IS_WND_TYPE(pWnd, CListCtrl, WC_LISTVIEW)) { LVHITTESTINFO lvhti = { { point.x, point.y }, 0 }; ListView_HitTest(pWnd->GetSafeHwnd(), &lvhti); // remove previous highlighting if (m_nLVPrevHilite != -1 && m_nLVPrevHilite != lvhti.iItem) { ListView_SetItemState(pWnd->GetSafeHwnd(), m_nLVPrevHilite, 0, LVIS_DROPHILITED); } if (lvhti.iItem != -1) { ListView_SetItemState(pWnd->GetSafeHwnd(), lvhti.iItem, LVIS_DROPHILITED, LVIS_DROPHILITED); m_nLVPrevHilite = lvhti.iItem; return bFilename ? DROPEFFECT_LINK : DROPEFFECT_COPY; } } else if (IS_WND_TYPE(pWnd, CEdit, WC_EDIT)) { if (!(pWnd->GetStyle() & ES_READONLY)) { return DROPEFFECT_COPY; } } else if (pWnd->IsKindOf(RUNTIME_CLASS(CDialog)) || pWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd))) { // allow dropping only on titlebar if ((pWnd->GetStyle() & WS_CAPTION) && point.y < 0) { return DROPEFFECT_COPY; } } } else { if (IS_WND_TYPE(pWnd, CTreeCtrl, WC_TREEVIEW)) { TreeView_SelectDropTarget(pWnd->GetSafeHwnd(), NULL); } else if (IS_WND_TYPE(pWnd, CListCtrl, WC_LISTVIEW)) { if (m_nLVPrevHilite != -1) { ListView_SetItemState(pWnd->GetSafeHwnd(), m_nLVPrevHilite, 0, LVIS_DROPHILITED); // all items } m_nLVPrevHilite = -1; } } // else return DROPEFFECT_NONE; }