Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
draglist.c
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 9k
Category:
Windows Kernel
Development Platform:
Visual C++
- #include "ctlspriv.h"
- #define DF_ACTUALLYDRAG 0x0001
- #define DF_DEFERRED 0x0002
- #define INITLINESPERSECOND 6
- #define VERTCHANGENUMLINES 25
- #define TIMERID 238
- #define TIMERLEN 50
- #define DX_INSERT 16
- #define DY_INSERT 16
- typedef struct {
- HWND hwndDrag;
- UINT uFlags;
- } DRAGPROP, *PDRAGPROP;
- UINT uDragListMsg = 0;
- #ifndef WINNT
- #pragma data_seg(DATASEG_READONLY)
- #endif
- const TCHAR szDragListMsgString[] = DRAGLISTMSGSTRING;
- #ifndef WINNT
- #pragma data_seg()
- #endif
- BOOL NEAR PASCAL PtInLBItem(HWND hLB, int nItem, POINT pt, int xInflate, int yInflate)
- {
- RECT rc;
- if (nItem < 0)
- nItem = (int)SendMessage(hLB, LB_GETCURSEL, 0, 0L);
- if (SendMessage(hLB, LB_GETITEMRECT, nItem, (LPARAM)(LPRECT)&rc) == LB_ERR)
- return(FALSE);
- InflateRect(&rc, xInflate, yInflate);
- return(PtInRect(&rc, pt));
- }
- /*
- * DragListSubclassProc
- * --------------------
- *
- * Window procedure for subclassed list boxes
- */
- LRESULT CALLBACK DragListSubclassProc(HWND hLB, UINT uMsg, WPARAM wParam,
- LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
- {
- PDRAGPROP pDragProp;
- DRAGLISTINFO sNotify;
- BOOL bDragging;
- POINT pt;
- pDragProp = (PDRAGPROP)dwRefData;
- bDragging = pDragProp->hwndDrag == hLB;
- switch (uMsg)
- {
- case WM_NCDESTROY:
- if (bDragging)
- SendMessage(hLB, WM_RBUTTONDOWN, 0, 0L); /* cancel drag */
- RemoveWindowSubclass(hLB, DragListSubclassProc, 0);
- if (pDragProp)
- LocalFree((HLOCAL)pDragProp);
- break;
- case WM_LBUTTONDOWN:
- {
- int nItem;
- if (bDragging) /* nested button-down */
- SendMessage(hLB, WM_RBUTTONDOWN, 0, 0L); /* cancel drag */
- SetFocus(hLB);
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- ClientToScreen(hLB, &pt);
- nItem = LBItemFromPt(hLB, pt, FALSE);
- if (nItem >= 0)
- {
- SendMessage(hLB, LB_SETCURSEL, nItem, 0L);
- if (GetWindowLong(hLB, GWL_STYLE) & LBS_NOTIFY)
- SendMessage(GetParent(hLB), WM_COMMAND,
- GET_WM_COMMAND_MPS(GetDlgCtrlID(hLB), hLB, LBN_SELCHANGE));
- sNotify.uNotification = DL_BEGINDRAG;
- goto QueryParent;
- }
- else
- goto FakeDrag;
- }
- case WM_TIMER:
- if (wParam != TIMERID)
- break;
- lParam = GetMessagePosClient(hLB, &pt);
- // fall through
- case WM_MOUSEMOVE:
- if (bDragging)
- {
- HWND hwndParent;
- LRESULT lResult;
- /* We may be just simulating a drag, but not actually doing
- * anything.
- */
- if (!(pDragProp->uFlags&DF_ACTUALLYDRAG))
- return(0L);
- /* We don't want to do any dragging until the user has dragged
- * outside of the current selection.
- */
- if (pDragProp->uFlags & DF_DEFERRED)
- {
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- if (PtInLBItem(hLB, -1, pt, 0, 4))
- return 0;
- pDragProp->uFlags &= ~DF_DEFERRED;
- }
- sNotify.uNotification = DL_DRAGGING;
- QueryParent:
- hwndParent = GetParent(hLB);
- sNotify.hWnd = hLB;
- sNotify.ptCursor.x = GET_X_LPARAM(lParam);
- sNotify.ptCursor.y = GET_Y_LPARAM(lParam);
- ClientToScreen(hLB, &sNotify.ptCursor);
- lResult = SendMessage(hwndParent, uDragListMsg, GetDlgCtrlID(hLB),
- (LPARAM)(LPDRAGLISTINFO)&sNotify);
- if (uMsg == WM_LBUTTONDOWN)
- {
- /* Some things may not be draggable
- */
- if (lResult)
- {
- SetTimer(hLB, TIMERID, TIMERLEN, NULL);
- pDragProp->uFlags = DF_DEFERRED | DF_ACTUALLYDRAG;
- }
- else
- {
- FakeDrag:
- pDragProp->uFlags = 0;
- }
- /* Set capture and change mouse cursor
- */
- pDragProp->hwndDrag = hLB;
- SetCapture(hLB);
- }
- else
- {
- switch (lResult)
- {
- case DL_STOPCURSOR:
- SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_NO)));
- break;
- case DL_COPYCURSOR:
- SetCursor(LoadCursor(HINST_THISDLL, MAKEINTRESOURCE(IDC_COPY)));
- break;
- case DL_MOVECURSOR:
- SetCursor(LoadCursor(HINST_THISDLL, MAKEINTRESOURCE(IDC_MOVE)));
- break;
- default:
- break;
- }
- }
- /* Don't call the def proc, since it may try to change the
- * selection or set timers or things like that.
- */
- return(0L);
- }
- break;
- case WM_RBUTTONDOWN:
- case WM_LBUTTONUP:
- /* if we are capturing mouse - release it and check for acceptable place
- * where mouse is now to decide drop or not
- */
- if (bDragging)
- {
- HWND hwndParent;
- pDragProp->hwndDrag = NULL;
- KillTimer(hLB, TIMERID);
- ReleaseCapture();
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- hwndParent = GetParent(hLB);
- sNotify.uNotification = uMsg==WM_LBUTTONUP ? DL_DROPPED : DL_CANCELDRAG;
- sNotify.hWnd = hLB;
- sNotify.ptCursor.x = GET_X_LPARAM(lParam);
- sNotify.ptCursor.y = GET_Y_LPARAM(lParam);
- ClientToScreen(hLB, &sNotify.ptCursor);
- SendMessage(hwndParent, uDragListMsg, GetDlgCtrlID(hLB),
- (LPARAM)(LPDRAGLISTINFO)&sNotify);
- /* We need to make sure to return 0 in case this is from a
- * keyboard message.
- */
- return(0L);
- }
- break;
- case WM_GETDLGCODE:
- if (bDragging)
- {
- return (DefSubclassProc(hLB, uMsg, wParam, lParam) |
- DLGC_WANTMESSAGE);
- }
- break;
- case WM_KEYDOWN:
- if (wParam == VK_ESCAPE)
- {
- SendMessage(hLB, WM_RBUTTONDOWN, 0, 0L);
- }
- // fall through
- case WM_CHAR:
- case WM_KEYUP:
- /* We don't want the listbox processing this if we are dragging.
- */
- if (bDragging)
- return(0L);
- break;
- default:
- break;
- }
- return(DefSubclassProc(hLB, uMsg, wParam, lParam));
- }
- BOOL WINAPI MakeDragList(HWND hLB)
- {
- PDRAGPROP pDragProp;
- if (!uDragListMsg)
- uDragListMsg = RegisterWindowMessage(szDragListMsgString);
- /* Check that we have not already subclassed this window.
- */
- if (GetWindowSubclass(hLB, DragListSubclassProc, 0, NULL))
- return(TRUE);
- pDragProp = (PDRAGPROP)LocalAlloc(LPTR, sizeof(DRAGPROP));
- if (!pDragProp)
- return(FALSE);
- if (!SetWindowSubclass(hLB, DragListSubclassProc, 0, (DWORD_PTR)pDragProp))
- {
- LocalFree((HLOCAL)pDragProp);
- return(FALSE);
- }
- return(TRUE);
- }
- int WINAPI LBItemFromPt(HWND hLB, POINT pt, BOOL bAutoScroll)
- {
- static LONG dwLastScroll = 0;
- RECT rc;
- DWORD dwNow;
- int nItem;
- WORD wScrollDelay, wActualDelay;
- ScreenToClient(hLB, &pt);
- GetClientRect(hLB, &rc);
- nItem = (int)SendMessage(hLB, LB_GETTOPINDEX, 0, 0L);
- /* Is the point in the LB client area?
- */
- if (PtInRect(&rc, pt))
- {
- /* Check each visible item in turn.
- */
- for ( ; ; ++nItem)
- {
- if (SendMessage(hLB, LB_GETITEMRECT, nItem, (LPARAM)(LPRECT)&rc)
- == LB_ERR)
- break;
- if (PtInRect(&rc, pt))
- return(nItem);
- }
- }
- else
- {
- /* If we want autoscroll and the point is directly above or below the
- * LB, determine the direction and if it is time to scroll yet.
- */
- if (bAutoScroll && (UINT)pt.x<(UINT)rc.right)
- {
- if (pt.y <= 0)
- {
- --nItem;
- }
- else
- {
- ++nItem;
- pt.y = rc.bottom - pt.y;
- }
- wScrollDelay = (WORD)(1000 /
- (INITLINESPERSECOND - pt.y/VERTCHANGENUMLINES));
- dwNow = GetTickCount();
- wActualDelay = (WORD)(dwNow - dwLastScroll);
- if (wActualDelay > wScrollDelay)
- {
- /* This will the actual number of scrolls per second to be
- * much closer to the required number.
- */
- if (wActualDelay > wScrollDelay * 2)
- dwLastScroll = dwNow;
- else
- dwLastScroll += wScrollDelay;
- SendMessage(hLB, LB_SETTOPINDEX, nItem, 0L);
- }
- }
- }
- return(-1);
- }
- void WINAPI DrawInsert(HWND hwndParent, HWND hLB, int nItem)
- {
- static POINT ptLastInsert;
- static int nLastInsert = -1;
- RECT rc;
- /* Erase the old mark if necessary
- */
- if (nLastInsert>=0 && nItem!=nLastInsert)
- {
- rc.left = ptLastInsert.x;
- rc.top = ptLastInsert.y;
- rc.right = rc.left + DX_INSERT;
- rc.bottom = rc.top + DY_INSERT;
- /* Need to update immediately in case the insert rects overlap.
- */
- InvalidateRect(hwndParent, &rc, TRUE);
- UpdateWindow(hwndParent);
- nLastInsert = -1;
- }
- /* Draw a new mark if necessary
- */
- if (nItem!=nLastInsert && nItem>=0)
- {
- HICON hInsert = NULL;
- if (!hInsert)
- hInsert = LoadIcon(HINST_THISDLL, MAKEINTRESOURCE(IDI_INSERT));
- if (hInsert)
- {
- HDC hDC;
- GetWindowRect(hLB, &rc);
- ScreenToClient(hLB, (LPPOINT)&rc);
- ptLastInsert.x = rc.left - DX_INSERT;
- SendMessage(hLB, LB_GETITEMRECT, nItem, (LPARAM)(LPRECT)&rc);
- ptLastInsert.y = rc.top - DY_INSERT/2;
- nLastInsert = nItem;
- ClientToScreen(hLB, &ptLastInsert);
- ScreenToClient(hwndParent, &ptLastInsert);
- hDC = GetDC(hwndParent);
- DrawIcon(hDC, ptLastInsert.x, ptLastInsert.y, hInsert);
- ReleaseDC(hwndParent, hDC);
- }
- }
- }