******************** * C4W2NTK TUTORIAL ******************** * This is a NTK emultation of the original C4W sample named: * \CLIP4WIN\SOURCE\DROP.PRG * * * The NTK make procedure is: * MKRAD DROP * * I can't beleive, it's Clip4Win! * Powered by NTK - http://www.ntkproject.com ******************** //////////////////////////// // // Clip-4-Win drop file demo // // Copyright (C) 1992 Skelton Software, Kendal Cottage, Hillam, Leeds, UK. // All Rights Reserved. // // // Make : rmake drop // // //////////////////////////// #define WIN_WANT_ALL #include "windows.ch" // NTK: just add that for NTK #include "ntkmsg.ch" // Window message def. #include "ntkmenus.ch" // Window menu def. #include "ntkgdi.ch" // Window gdi & font def. #include "c4w2ntk.ch" // C4W msg def and NTK translations #include "ntkcmd.ch" // NTK rad msg and cmd def. (i.e. @...Say ) #include "ntkdll.ch" // NTK Dll cmd def. (i.e. _DLL, _DLL32, Declare Function ) #include "drop.ch " #define R_LEFT 1 //dimensions of rectangle #define R_TOP 2 #define R_RIGHT 3 #define R_BOTTOM 4 #define FILE_NAME_LENGTH 60 static cAppName := "Clip-4-Win" static hWnd, hInst, hPrevInst, nCmdShow static cText := "" static aWnd := {}, aAction := {} // for event handlers function main() local hMenu, nEvent REQUEST HB_GT_GUI_DEFAULT // for [xHarbour] version > 0.99.7. We want to hear tone() hWnd = WinSetup(cAppName, "Clip-4-Win drop file demo") hInst = _GetInstance() hMenu = MenuSetup() HideCaret(hWnd) AddHandler(hWnd, {|nEvent| MainEvent(nEvent)}) do while .t. do while (nEvent := ChkEvent()) == EVENT_NONE // some "background" processing could go here enddo HandleEvent(nEvent) do case case nEvent == EVENT_QUIT DoExit() endcase enddo return 0 procedure MainEvent(nEvent) local hOldWnd do case case nEvent == EVENT_REDRAW hOldWnd = SelectWindow(hWnd) @ 10, 10 say "(This window intentionally left blank.)" SelectWindow(hOldWnd) endcase return procedure DoExit() // NTK: MessageBox(0, "Thanks for running this Clip-4-Win demo", "Clip-4-Win Demo Exiting", MB_OK) MessageBox(0, "Thanks for running this Clip-4-Win demo"+chr(13)+"Powered by NTK - http://www.ntkproject.com", "Clip-4-Win Demo Exiting", MB_OK) quit return procedure PaintWindow (hWnd, nColor) local hBrush local hDC local aRect hDC = GetDC (hWnd) aRect = GetClientRect (hWnd) hBrush = CreateSolidBrush (nColor ) hBrush = SelectObject (hDC, hBrush) Rectangle (hDC, aRect[R_LEFT], aRect[R_TOP], aRect[R_RIGHT], aRect[R_BOTTOM]) DeleteObject (SelectObject (hDC, hBrush)) ReleaseDC (hWnd, hDC) return procedure PaintTheBlock (hCtrl, nColor) InvalidateRect (hCtrl) UpdateWindow (hCtrl) PaintWindow (hCtrl, nColor) return function DialogHandler(hDlg, nMsg, nwParam, nlParam) static hCtrlBlk1, hCtrlBlk2 local hFilesInfo local cFileName := "" local cBuf:=" " static arZone1, arZone2, arDlg //arrays for bounding rectangles // of zones and dialog window local aPointDrop := {0, 0} //array that will contain coordinates //of point where the file(s) were dropped local nFilesDropped, nIndex do case case nMsg == WM_INITDIALOG hCtrlBlk1 = GetDlgItem(hDlg, IDD_ZONE1) hCtrlBlk2 = GetDlgItem(hDlg, IDD_ZONE2) SetFocus(GetDlgItem(hDlg, IDOK)) //enable WM_DROPFILES posting DragAcceptFiles(hDlg, .T.) arZone1 = GetWindowRect(hCtrlBlk1) arZone2 = GetWindowRect(hCtrlBlk2) arDlg = GetWindowRect(hDlg) return 1 // want system to set the focus case nMsg == WM_SYSCOMMAND if nwParam == SC_CLOSE // system menu double click, or Alt-F4 EndDialog(hDlg, .T.) endif case nMsg == WM_COMMAND do case case nwParam == IDOK EndDialog( hDlg, .T.) return 1 // means msg has been processed endcase case nMsg == WM_PAINT PaintTheBlock (hCtrlBlk1, RGB(255,0,0)) PaintTheBlock (hCtrlBlk2, RGB(0,0,255)) case nMsg == WM_DROPFILES hFilesInfo = nwParam // Retrieve the window coordinates of the mouse // pointer when the drop was made DragQueryPoint ( nwParam, @aPointDrop) // Get the total number of files dropped nFilesDropped = DragQueryFile (hFilesInfo; , -1 ; , 0 ; , 0) // test: MessageBox(hDlg, cBuf, str(nFilesDropped) + " file(s):" , MB_OK+MB_TOPMOST) // Retrieve each file name and add to the buffer string for nIndex = 0 to nFilesDropped-1 cFileName := SPACE(FILE_NAME_LENGTH) DragQueryFile (hFilesInfo; ,nIndex; ,@cFileName; ,FILE_NAME_LENGTH) // test: MessageBox(hDlg, cFileName, " file #"+str(nFilesDropped)+" is:" , MB_OK+MB_TOPMOST) cBuf += cFileName + " " next DragFinish (hFilesInfo) aPointDrop[1] += arDlg[1] aPointDrop[2] += arDlg[2] if ((aPointDrop[1] >= arZone1[R_LEFT]) .AND. (aPointDrop[1] <= arZone1[R_RIGHT]); .AND. (aPointDrop[2] >= arZone1[R_TOP]) .AND. (aPointDrop[2] <=arZone1[R_BOTTOM])) cBuf += "were dropped in ZONE1 " elseif ((aPointDrop[1] >= arZone2[R_LEFT]) .AND. (aPointDrop[1] <= arZone2[R_RIGHT]); .AND. (aPointDrop[2] >= arZone2[R_TOP]) .AND. (aPointDrop[2] <=arZone2[R_BOTTOM])) cBuf += "were dropped in ZONE2 " else cBuf+= "were dropped outside of zones " endif MessageBox(hDlg, cBuf, str(nFilesDropped) + " file(s):" , MB_OK+MB_TOPMOST) return 1 endcase return 0 // means msg not processed (and want default action) procedure DoDrop() DialogBox( , "DropBox", hWnd, ; {|hDlg, msg, wparam, lparam| ; DialogHandler(hDlg, msg, wparam, lparam)}) return function MenuSetup() local hWnd := SelectWindow(), hMenu, hPopupMenu if (hMenu := GetMenu(hWnd)) != nil DestroyMenu(hMenu) endif // do new one (forget old value) hMenu = CreateMenu() hPopupMenu = CreatePopupMenu() // NTK: cannot be here - AppendMenu(hMenu, "file", MF_ENABLED + MF_POPUP, "&File", hPopupMenu) AppendMenu(hPopupMenu, "invoked", MF_ENABLED + MF_STRING, "Invoke &drop ...", {|| DoDrop()}) AppendMenu(hPopupMenu, "", MF_SEPARATOR) AppendMenu(hPopupMenu, "exit", MF_ENABLED + MF_STRING, "E&xit", {|| DoExit()}) AppendMenu(hMenu, "file", MF_ENABLED + MF_POPUP, "&File", hPopupMenu) SetMenu(hWnd, hMenu) return hMenu ** // NTK: ** Those functions are now integrated in \WNTK4HRB\NTKLIB\RADEX\rNTKC4W.PRG since July 2009 ** function AddHandler(hWnd, bAction) // --> nId (for use with DelHandler) aadd(aWnd, hWnd) aadd(aAction, bAction) return len(aWnd) procedure DelHandler(nId) adel(aWnd, nId) asize(aWnd, len(aWnd) - 1) adel(aAction, nId) asize(aAction, len(aAction) - 1) return procedure HandleEvent(nEvent) local hWnd := _LasthWnd(), i := 0 do while (i := ascan(aWnd, hWnd, ++i)) != 0 eval(aAction[i], nEvent) enddo if nEvent == EVENT_DESTROY // clean up, so the event handler needn't bother do while (i := ascan(aWnd, hWnd)) != 0 DelHandler(i) enddo endif return function WinNew(cAppName, cTitle, nX, nY, nWidth, nHeight) local hWin, hInst, nCmdShow hInst = _GetInstance() // Don't work with NTK nCmdShow = _GetnCmdShow() nCmdShow = SW_SHOW hWin = CreateWindow(cAppName, ; // window class cTitle, ; // caption for title bar WS_OVERLAPPEDWINDOW,; // window style nX, ; // x co-ordinate nY, ; // y co-ordinate nWidth, ; // width nHeight, ; // height hWnd, ; // hWnd of parent 0, ; // hMenu of menu (none yet) hInst) // our own app instance if hWin == 0 // probably out of resources MessageBox( , "Can't create window", "Error", MB_OK) return nil endif HideCaret(hWin) // make sure it's displayed ... ShowWindow(hWin, nCmdShow) // ... and up to date UpdateWindow(hWin) return hWin *********************************************************************************************** *********************************************************************************************** ************************** WRAPPER's WIN32 API FUNCTION SOURCE CODE ********************** *********************************************************************************************** *********************************************************************************************** *********************************************************************************************** // ** The DragAcceptFiles function registers whether a window accepts dropped files. _DLL FUNCTION DragAcceptFiles( hWnd as HWND, fAccept as BOOL ) AS void PASCAL:Shell32.DragAcceptFiles // ** The DragFinish function releases memory that Windows allocated for use in transferring filenames to the application. _DLL FUNCTION DragFinish( hDrop as HANDLE ) AS void PASCAL:Shell32.DragFinish // ** The DragQueryFile function retrieves the filenames of dropped files. FUNCTION DragQueryFile( hDrop, nIndex, cFileName, nLen ) // --> nResult LOCAL nResult LOCAL cBuf := IIF( EMPTY(nLen), SPACE(FILE_NAME_LENGTH), SPACE(nLen) ) nResult := _DragQueryFile( hDrop, nIndex, @cBuf, nLen ) cFileName := ALLTRIM( STRTRAN( LEFT(cBuf, nLen), chr(0), "|", "" ) ) cFileName := STRTRAN( cFileName, "|", "" ) // Remove the two null chars (if any) stored at the end of returned cBuf. cBuf := nil RETURN(nResult) _DLL FUNCTION _DragQueryFile( hDrop as HANDLE, nIndex as UINT, @cFileName as STRING, nLength as UINT ) AS uint PASCAL:Shell32.DragQueryFile // ** The DragQueryPoint function returns the mouse position when a file is dropped FUNCTION DragQueryPoint( hDrop, aPointDrop ) // --> nInClient LOCAL c1, c2, cPointDrop LOCAL n1, n2, nRet c1 := aPointDrop[1] c2 := aPointDrop[2] cPointDrop := L2BIN(C1)+L2BIN(C2) nRet := _DragQueryPoint( hDrop, @cPointDrop ) n1 = BIN2L( SUBSTR( cPointDrop ,1,4) ) n2 = BIN2L( SUBSTR( cPointDrop ,5,4) ) aPointDrop := { n1, n2 } RETURN( nRet ) _DLL FUNCTION _DragQueryPoint( hDrop as HANDLE, @aPointDrop as STRING ) AS bool PASCAL:Shell32.DragQueryPoint *********************************************************************************************** *********************************************************************************************** ***********************************************************************************************