home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 10.ddi / DRAGDROP.ZIP / DRAGDROP.CPP next >
Encoding:
Text File  |  1992-06-10  |  11.5 KB  |  371 lines

  1. // ObjectWindows - (C) Copyright 1992 by Borland International
  2. //
  3. // Dragdrop.cpp - Drag and Drop example in OWL
  4.  
  5. // Beginning of file dragdrp.cpp
  6.  
  7. /* --------------------------------------------------------------
  8.     This is a code example using the Drag and Drop feature in
  9.     Windows 3.1 with OWL.  The example shows how to drop files
  10.     into the client area of the main window and then print
  11.     out the file names that were dropped in the client area.
  12.     TMyWindow maintains this information in a List of Lists.
  13.     Each sub List is a set of files that were dropped.  The code
  14.     is well commented with Steps to follow the creation of the
  15.     application as well as comments for common pitfalls and
  16.     important lines of code that affect the performance of your
  17.     application.
  18.  --------------------------------------------------------------- */
  19.  
  20. char HelpText[]=
  21. "\n\rThis application must be run under Windows 3.1.\n\r \
  22. Bring up the Windows 3.1 File Manager.  Select a file\n\r \
  23. with the left mouse button and keep the button down.\n\r \
  24. Now drag the mouse over until it is on top of the drag\n\r \
  25. n' drop window client area.  Now release the left mouse\n\r \
  26. button.  You have just dragged and dropped a file.  To\n\r \
  27. drag a group of files, select the group with the Shift\n\r \
  28. and arrow keys and then repeat the previous directions.";
  29.  
  30. //#define STRICT    // define STRICT to provide maximum type safety
  31.                     // as defined by Microsoft
  32.                     // Already defined in project and make file
  33.  
  34. //#define WIN31        // define WIN31 for Windows 3.1 features
  35.                     // Already defined in project and make file
  36.  
  37. #include <owl.h>
  38. #include <string.h>
  39. #include <list.h>
  40. /***************************************************************
  41.     Step 0:
  42.     This is the header file which declares the Drag and Drop
  43.     functions. The functions are in SHELL.DLL
  44. ****************************************************************/
  45. #include <shellapi.h>
  46.  
  47. class TMyApp : public TApplication
  48. {
  49. public:
  50.     TMyApp(LPSTR AName, HINSTANCE hInstance, HINSTANCE hPrevInstance,
  51.     LPSTR lpCmdLine, int nCmdShow)
  52.     : TApplication(AName, hInstance, hPrevInstance, lpCmdLine, nCmdShow) {};
  53.     virtual void InitMainWindow();
  54. };
  55.  
  56. _CLASSDEF( TMyWindow );
  57. class TMyWindow : public TWindow
  58. {
  59.     BOOL GetHelp;
  60. protected:
  61.     List *liAllFiles;    // liAllFiles is a pointer to a linked list.
  62.                         // Each Object in the list will also be a list.
  63.                         // These lists will contain the names of the
  64.                         // files that have been dragged & dropped in
  65.                         // a group.
  66. public:
  67.     TMyWindow( PTWindowsObject, LPSTR );
  68.     virtual void SetupWindow();
  69.     virtual void ShutDownWindow();
  70.     virtual LPSTR GetClassName();
  71.     virtual void GetWindowClass( WNDCLASS _FAR & );
  72.  
  73. /************************************************************
  74.     Step 2:
  75.     Dispatch a message to WM_DROPFILES
  76. *************************************************************/
  77.     virtual void WMDropFiles( RTMessage ) = [ WM_FIRST + WM_DROPFILES ];
  78.  
  79.     void AddFiles( List * );
  80.     virtual void Paint( HDC , PAINTSTRUCT _FAR & );
  81.     virtual void HowTo101( RTMessage msg)=[CM_FIRST + 101]
  82.     {
  83.         GetHelp=TRUE;
  84.         InvalidateRect( HWindow, NULL, TRUE );
  85.         UpdateWindow( HWindow );
  86.     }
  87.     virtual void View102( RTMessage msg)=[CM_FIRST + 102]
  88.     {
  89.         GetHelp=FALSE;
  90.         InvalidateRect( HWindow, NULL, TRUE );
  91.         UpdateWindow( HWindow );
  92.     }
  93.     virtual void Clear103( RTMessage msg)=[CM_FIRST + 103]
  94.     {
  95.         GetHelp=FALSE;
  96.         delete liAllFiles;
  97.         liAllFiles = new List;
  98.         InvalidateRect( HWindow, NULL, TRUE );
  99.         UpdateWindow( HWindow );
  100.     }
  101.     virtual void About104( RTMessage msg)=[CM_FIRST + 104]
  102.     {
  103.         MessageBox(HWindow,"DRAG n' DROP\nWritten using ObjectWindows\nCopyright (c) 1992 Borland",
  104.                     "ABOUT BOX",MB_OK);
  105.     }
  106.  
  107. };
  108.  
  109. /************************************************************
  110.  * liAllFiles of TMyWindow is a linked list of Lists.
  111.  * Each List in the linked list will contain the file names
  112.  * that were received during a WM_DROPFILES messages.
  113.  * The following declarations are to build up the object
  114.  * which will desribe an individual file that was droped
  115.  * during one of these messages.
  116.  * Since these objects are derived from Object, they
  117.  * can be inserted into a List.
  118. *************************************************************/
  119. #define __NonAbstractObject  __firstUserClass
  120.  
  121. class NonAbstractObject : public Object
  122. /************************************************************
  123.     This is a base class to take care of redefining all the
  124.     pure virtual functions that make Object abstract.
  125. *************************************************************/
  126.  
  127. {
  128.     virtual classType isA() const { return __NonAbstractObject; }
  129.     virtual Pchar nameOf()  const { return "NonAbstractObject"; }
  130.     virtual hashValueType hashValue() const { return ( hashValueType )this; }
  131.     virtual int   isEqual(RCObject test)  const
  132.         { return this ==  &(NonAbstractObject &)test; }
  133.     virtual void             printOn(Rostream outputStream) const
  134.         { outputStream << nameOf() << endl; }
  135. };
  136.  
  137. class TFileDrop : public NonAbstractObject
  138. /*************************************************************
  139.     This class Maintains information about a dropped file,
  140.     its name, where it was dropped, and whether or not it
  141.     was in the client area
  142. **************************************************************/
  143. {
  144. public:
  145.     char *lpFileName;
  146.     POINT pPoint;
  147.     BOOL inClientArea;
  148.  
  149.     TFileDrop( char * , POINT &, BOOL );
  150.     char * WhoAmI();
  151.     ~TFileDrop() { delete lpFileName; }
  152. };
  153.  
  154.  
  155. TFileDrop::TFileDrop( char *FileName , POINT &p, BOOL inClient )
  156. {
  157.     lpFileName = new char[  strlen( FileName ) + 1 ];
  158.     strcpy( lpFileName, FileName );
  159.     pPoint.x = p.x;
  160.     pPoint.y = p.y;
  161.     inClientArea = inClient;
  162. }
  163.  
  164. char *TFileDrop::WhoAmI()
  165. {
  166.     static char buffer[ 80 ];
  167.  
  168.     wsprintf( buffer, "File: %s [ %d , %d ] inClient: %d",
  169.             (LPSTR)lpFileName, pPoint.x , pPoint.y, inClientArea );
  170.  
  171. //WARNING!!:  Serious problem recognized:
  172.             //In the small model, without the typecast,
  173.             //lpFileName was two bytes on the stack of which
  174.             //wsprintf took 4.
  175.  
  176.     return buffer;
  177. }
  178.  
  179.  
  180. void TMyWindow::WMDropFiles( RTMessage msg )
  181. /*********************************************************
  182.     Step 3:
  183.     Retrieve a handle to an internal data structure in
  184.     SHELL.DLL.  Get the info out of it.
  185. **********************************************************/
  186. {
  187. /*********************************************************
  188.     Step 4:
  189.     Identify the handle
  190. **********************************************************/
  191.     HDROP hDrop = (HDROP)msg.WParam;
  192.                 //msg.WParam contains the Handle to the
  193.                 //internal data structure which has
  194.                 //information about the dropped file(s)
  195.  
  196. /* ************************************************************
  197.     Step 5:
  198.     Find out how many files are dropped,
  199.     To find out total number of dropped files,
  200.     pass 0xFFFF for index parameter to DragQueryFile
  201.    ************************************************************/
  202.     int TotalNumberOfFiles = DragQueryFile( hDrop , 0xFFFF, NULL, 0 );
  203.     GetHelp=FALSE;
  204.  
  205.     List *liFiles = new List;
  206.  
  207.     for ( int i = 0; i < TotalNumberOfFiles ; i++ )
  208.     {
  209. /************************************************************
  210.     Step 6:
  211.     Get the length of a filename by telling DragQueryFile
  212.     which file your querying about ( i ), and passing NULL
  213.     for the buffer parameter.
  214. *************************************************************/
  215.         int nFileLength  = DragQueryFile( hDrop , i , NULL, 0 );
  216.  
  217.         char *pszFileName = new char [ nFileLength + 1];
  218.  
  219. /************************************************************
  220.     Step 7:
  221.     Copy a file name.   Tell DragQueryFile the file
  222.     your interested in (i) and the length of your buffer.
  223.     NOTE: Make sure that the length is 1 more then the filename
  224.     to make room for the null charater!
  225. *************************************************************/
  226.         DragQueryFile( hDrop , i, pszFileName, nFileLength + 1 );
  227.             //copies over the filename
  228.  
  229.         POINT pPoint ;
  230.         BOOL inClientArea;
  231.  
  232. /**************************************************************
  233.     Step 8:
  234.     Getting the file dropped. The location is relative to your
  235.     client coordinates, and will have negative values if dropped in
  236.     the non client parts of the window.
  237.  
  238.     DragQueryPoint copies that point where the file was dropped
  239.     and returns whether or not the point is in the client area.
  240.     Regardless of whether or not the file is dropped in the client
  241.     or non-client area of the window, you will still receive the
  242.     file name.
  243. ***************************************************************/
  244.  
  245.         inClientArea = DragQueryPoint( hDrop , &pPoint );
  246.  
  247.         liFiles->add( * new TFileDrop( pszFileName , pPoint , inClientArea ));
  248.  
  249.     }
  250.     AddFiles( liFiles );    //Add this sublist of dropped files
  251.                             //to the big list.
  252. /************************************************************
  253.     Step 9:
  254.     Release the memory shell allocated for this handle
  255.     with DragFinish.
  256.     NOTE: This is a real easy step to forget and could
  257.     explain memory leaks and incorrect program performance.
  258. *************************************************************/
  259.     DragFinish( hDrop );
  260. }
  261.  
  262. void TMyWindow::AddFiles( List *pliFiles )
  263. {
  264.     liAllFiles->add( *pliFiles );
  265.     InvalidateRect( HWindow, NULL, TRUE );
  266.     UpdateWindow( HWindow );
  267. }
  268.  
  269. TMyWindow::TMyWindow( PTWindowsObject p, LPSTR s ) : TWindow( p, s )
  270. {
  271.     liAllFiles = new List;
  272.     GetHelp=TRUE;
  273. }
  274.  
  275. void TMyWindow::Paint( HDC hdc, PAINTSTRUCT _FAR &)
  276. {
  277.     RECT rect;
  278.  
  279.     if(GetHelp)
  280.     {
  281.         GetClientRect(HWindow,&rect);
  282.         DrawText(hdc, HelpText, strlen(HelpText),&rect,DT_NOCLIP|DT_CENTER|DT_WORDBREAK);
  283.     }
  284.     else
  285.     {
  286.         SetBkMode ( hdc , TRANSPARENT );
  287.  
  288.         // get a list iterator for the main list.
  289.         ListIterator liMainList = ( ListIterator & )
  290.         liAllFiles->initIterator();
  291.         int i = 0;
  292.  
  293.         while ( liMainList != 0 )
  294.         {
  295.             // for each element in the main list, get a
  296.             // list iterator for that element, which is itself
  297.             // a list, call it a sub list
  298.  
  299.             ListIterator liSubList =  ( ListIterator & )
  300.                 ((List &)( liMainList.current() )).initIterator();
  301.             while ( liSubList != 0 )
  302.             {
  303.                 // for each element in the sub list, get the string
  304.                 // which describes it, we know these elements are
  305.                 // instances of the TFileDrop class
  306.  
  307.                 char *string = ((TFileDrop &)(liSubList.current())).WhoAmI();
  308.  
  309.                 TextOut( hdc , 10 , 20 * i++ , string, strlen( string ) );
  310.                 liSubList++;
  311.             }
  312.             liMainList++;
  313.             i++;
  314.         }
  315.     }
  316. }
  317.  
  318. void TMyWindow::SetupWindow()
  319. {
  320.     TWindow::SetupWindow();
  321. /****************************************************************
  322.     Step 1:
  323.     calling DragAcceptFiles.  If you  pass FALSE, you're saying
  324.     I don't accept them anymore.  Notice how it takes an HWindow.
  325.     WARNING: Don't do this in the constructor!  HWindow is NOT
  326.     valid at that point.
  327. *****************************************************************/
  328.  
  329.     DragAcceptFiles( HWindow , TRUE );
  330. }
  331.  
  332. void TMyWindow::ShutDownWindow()
  333. {
  334. /****************************************************************
  335.     Step 10:
  336.     Don't accept files anymore
  337. *****************************************************************/
  338.  
  339.     DragAcceptFiles( HWindow , FALSE );
  340.     delete liAllFiles;
  341.     TWindow::ShutDownWindow();
  342. }
  343.  
  344. LPSTR TMyWindow::GetClassName()
  345. {
  346.     return "MYWINDOW";
  347. }
  348.  
  349. void TMyWindow::GetWindowClass( WNDCLASS _FAR & wc )
  350. {
  351.     TWindow::GetWindowClass( wc );
  352.     wc.lpszMenuName=(LPSTR)"DRAGMENU";
  353. }
  354.  
  355. void TMyApp::InitMainWindow()
  356. {
  357.     MainWindow = new TMyWindow(NULL, Name);
  358. }
  359.  
  360.  
  361. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  362.     LPSTR lpCmdLine, int nCmdShow)
  363. {
  364.     TMyApp MyApp("Drag & Drop Example", hInstance, hPrevInstance,
  365.             lpCmdLine, nCmdShow);
  366.     MyApp.Run();
  367.     return MyApp.Status;
  368. }
  369.  
  370. // end of file dragdrp.cpp
  371.