Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/27/2013 in all areas

  1. Hello, I just made another TCP server. I will use the server for data collection and a lot of clients can get the data from TCP. I now use it for UDP broadcast some devices to get their IP's. You can also use it for chat's. It is very low level, but so you have more options than with the pure AutoIt functions. Just start the server in SciTE to see the console outputs. Then you can start up to 63 clients to talk to the server. I hope you like it. Server script: #include "socket_UDF.au3" ;funkey 2013.06.21 _WSAStartup() Global $iSocket Global $iReturn Global $iPort = 20500 Global $sIP_Connected Global $iPort_Connected Global $tBuffer = DllStructCreate("char buffer[512]") $iSocket = _socket($AF_INET, $SOCK_STREAM, $IPPROTO_TCP) ConsoleWrite("Listen Socket: " & $iSocket & @CRLF) Global $tReUse = DllStructCreate("BOOLEAN reuse") DllStructSetData($tReUse, "reuse", True) ; enable reusing the same port $iReturn = _setsockopt($iSocket, $SOL_SOCKET, $SO_REUSEADDR, $tReUse) ; set reusing option for the port If $iReturn Then ConsoleWrite("SetSockOpt error setting reusing the same port!. Windows Sockets Error Codes: " & _WSAGetLastError() & @CRLF) EndIf $iReturn = _bind($iSocket, @IPAddress1, $iPort) ;local IP-Address and port to use If $iReturn Then ConsoleWrite("Bind error: " & $iReturn & @CRLF) ; 0 is OK EndIf $iReturn = _listen($iSocket, 1) If $iReturn Then ConsoleWrite("Listen error: " & $iReturn & @CRLF) ; 0 is OK EndIf Global $iNewSocket Global $tReadFds = DllStructCreate($tagFd_set) Global $tReadFds_Copy = DllStructCreate($tagFd_set) _FD_ZERO($tReadFds) _FD_SET($iSocket, $tReadFds) Global $iSocketMax = $iSocket Global $iSocketNow Global $sDataRcv While 1 DllCall('ntdll.dll', 'none', 'RtlMoveMemory', 'struct*', $tReadFds_Copy, 'struct*', $tReadFds, 'ULONG_PTR', DllStructGetSize($tReadFds)) $iReturn = _select($iSocketMax + 1, $tReadFds_Copy, 2000) ;timeout 2 seconds If _FD_ISSET($iSocket, $tReadFds_Copy) Then $iNewSocket = _accept($iSocket, $sIP_Connected, $iPort_Connected) _FD_SET($iNewSocket, $tReadFds) _FD_SHOW($tReadFds) If $iNewSocket > $iSocketMax Then $iSocketMax = $iNewSocket ConsoleWrite("New connected socket: " & $iNewSocket & @TAB & "IP: " & $sIP_Connected & @TAB & "Port: " & $iPort_Connected & @LF) EndIf For $i = 2 To DllStructGetData($tReadFds, "fd_count") $iSocketNow = DllStructGetData($tReadFds, "fd_array", $i) If _FD_ISSET($iSocketNow, $tReadFds_Copy) Then DllCall('ntdll.dll', 'none', 'RtlZeroMemory', 'struct*', $tBuffer, 'ULONG_PTR', DllStructGetSize($tBuffer)) If _recv($iSocketNow, $tBuffer) = $SOCKET_ERROR Then _closesocket($iSocketNow) _FD_CLR($iSocketNow, $tReadFds) Else $sDataRcv = DllStructGetData($tBuffer, 1) ConsoleWrite("Data received: " & $sDataRcv & @LF) If $sDataRcv == "CloseServer!" Then ExitLoop 2 EndIf EndIf EndIf Next WEnd For $i = 1 To DllStructGetData($tReadFds, "fd_count") _closesocket(DllStructGetData($tReadFds, "fd_array", $i)) Next _WSACleanup() Func _FD_SHOW(ByRef $tFd_set) For $i = 1 To DllStructGetData($tFd_set, "fd_count") ConsoleWrite($i & ":" & @TAB & DllStructGetData($tFd_set, "fd_array", $i) & @LF) Next EndFunc ;==>_FD_SHOWsocket_UDF and example.rar
    1 point
  2. Deadline of 1800 UTC 28 Nov 13 for any further comments and suggestions Hi, I mentioned in this thread that i was writing a new version of _ArrayDisplay - and here it is in Beta form. Changes as far as the user is concerned are: - 1. Script-breaking The $sReplace parameter has disappeared - see below for why it is no longer necessary - 2. The UDF changes the existing AutoIt data separator character to ChrW(0xF123) to create the ListView and then restores the existing separator on exit. If the user wants to copy data from the dialog, the separator character specified in the calling line is inserted in place of the UniCode one - as a default this is the existing character. In this case it is entirely up to the user to specify a different separator if the existing one is already included within the array. - 3. The ListView columns now expand to fit the widest item within them - the overall dialog has min/max widths to keep it visible and on screen. There is however a maximum column width limit to prevent a single column taking over the entire dialog - this can be reset by the user if needed. However, this limit is only enforced if the dialog woudl otherwise become wider than the screen. There is also a minimum width to ensure the default headers display correctly. - 4. Similarly, the dialog will adjust vertically to fit the number of rows - with max/min heights to keep things visible and on screen. - 5. Script-breaking If an error occurs because the UDF was not passed a 1D/2D array, a MsgBox will appear announce this rather than just returning an error and continuing the script as before. So the user does not need to add error checking code in their script as the UDF does this for them. This was added as the general opinion seemed to be that the function is basically intended for debugging and so it is useful to know that the array that was expected has not been created. The MsgBox offers a choice of exiting the script or of continuing - in which case it returns the same specific @error value as before. - 6. Script-breaking The $iArrayLimit parameter has been replaced with $sArrayRange which sets the contiguous rows/columns to display: "7" - Show rows 0-7 with all columns "7:" - Show rows 5-end with all columns "|7" - Show all rows with columns 0-7 "|7:" - Show all rows with columns 7-end "7|7" - Show rows 0-7 with columns 0-7 "5:7" - Show rows 5-7 with all columns "|5:7" - Show all rows with columns 5-7 "7|5:7" - Show rows 0-7 with columns 5-7 "5:7|7" - Show rows 5-7 with columns 0-7 "5:7|5:7" - Show rows 5-7 with columns 5-7 . - 7. Script-breaking The $iTranspose parameter has been replaced by $iFlags. Setting this parameter to 1 will transpose the array as before - but adding either 2 or 4 to the parameter will right or centre align the ListView columns. - 8. The ListView will displaya max of 64k lines (a Windows limitation) and 250 columns (arbitrarily set to keep the overall size reasonable). If the user tries to display over these limits a MsgBox announces that the array display has been truncated. Note that adjusting the array range displayed allows larger arrays to be displayed in sections. - 9. The buttons at the bottom of the dialog have been increased in number: - a. Copy Data & Hdr/Row - this copies the array (or the selected rows) to the clipboard adding full header and row identification. - b. Copy Data Only - this copies the array (or the selected rows) to the clipboard with no header or row identification. - c. Run User Function - run a user-defined function if its name was passed when calling _ArrayDisplay - the idea behind this is to allow the user to log, save or print the current state of the array. To this end, the full array and another array holding the selected rows are passed to this function which is entirely separate from the UDF and must be created and coded by the user to accept these parameters. The button is disabled if no function is specified. - d. Exit script - this exits the script immediately, just as can be the case with the error MsgBoxes. Given the debugging nature of the function, this could be useful if the array content is not as expected. - 10. If the user specifies a colour in the relevant parameter then the ListView will be displayed with alternate row colouring - no colour specifed means all rows are the same colour. - 11. If custom headers are uded they will be applied to as many columns as possible after which the standard default headers will be inserted. I should also mention that the new code runs in about half the time of the existing version, which is a major advantage for large arrays. Try increasing the test array size to [2000][100] to make it more obvious. Here is the new UDF for you to play with: <snip> Comments and (reasonable) further proposals are welcome - so over to you. M23 Edit: 1311281000UTC - new code added. Read the thread to follow the discussion if you wish - but all the salient info is in the above post And here is the proposed help file page for the new function: ###User Defined Function### _ArrayDisplay ###Description### Displays a 1D or 2D array array in a ListView ###Syntax### #include <Array.au3> _ArrayDisplay ( Const ByRef $avArray [, $sTitle = "ArrayDisplay" [, $sArrayRange = "" [, $iFlags = 0 [, $sUser_Separator = Default [, $sHeader = Default [, $iMax_ColWidth = Default [, $iAlt_Color = Default [, $sUser_Function = ""]]]]]]]] ) ###Parameters### @@ParamTable@@ $avArray Array to display $sTitle [optional] Title for dialog. Default = none. Array dimension(s) are always displayed. $sArrayRange [optional] Range of rows/columns to display. Default = display entire array (see below for limits). $iFlags [optional] Setting to 1 transposes a 2D array. Add 2 (right) or 4 (center) to alter columns alignment. Default = 0. $sUser_Separator [optional] Separator to use when copying data from dialog. Default = current separator character (usually "|"). $sHeader [optional] Column names in header (names separated by current separator character - usually "|"). Default see Remarks. $iMax_Colwidth [optional] Max width to which a column will expand to show content. Default = 350 pixels. $iAlt_Color [optional] If set ListView colors alternate rows. Default = all rows ListView color. $sUser_Function [optional] The user defined function to run. Default = none. @@End@@ ###ReturnValue### @@ReturnTable@@ Success: 1. Failure: MsgBox displayed, 0 returned and @error flag set as follows: @error: 1 - $avArray is not an array 2 - $avArray has too many dimensions (only 1D and 2D supported) @@End@@ ###Remarks### A MsgBox is displayed if the function is passed a non-array variable or the array has more than 2 dimensions. This will offer the chance to exit immediately or to continue the script. Only 65527 rows can be displayed - this is an AutoIt limitation on the total number of controls that can be displayed in a GUI. An abitrary display limit of 250 columns has also been set. If the user tries to display over these limits a MsgBox announces that the display has been truncated. Note that using $iArrayRange to set the elements to be displayed allows arrays larger than the display limits to be displayed in sections. The $sArrayRange parameter syntax is as follows: "7" - Show rows 0-7 with all columns "7:" - Show rows 7-end with all columns "|7" - Show all rows with columns 0-7 "|7:" - Show all rows with columns 7-end "7|7" - Show rows 0-7 with columns 0-7 "5:7" - Show rows 5-7 with all columns "|5:7" - Show all rows with columns 5-7 "7|5:7" - Show rows 0-7 with columns 5-7 "5:7|7" - Show rows 5-7 with columns 0-7 "5:7|5:7" - Show rows 5-7 with columns 5-7 $sHeader items separated by the current separator character will be used for as many columns as possible. If no, or not enough, custom items are defined then the default header of "Row|Col0" for 1D arrays or "Row|Col0|Col1|...|Col n" for 2D is substituted. The 4 buttons at the bottom of the dialog have the following functions: - Copy Data & Hdr/Row - copy the array or the selected row(s) to the clipboard adding full header and row identification. - Copy Data Only - copy the array or the selected row(s) to the clipboard with no header or row identification. - Run User Function - run the user-defined function passed in $sUser_Function. This function is entirely separate from the UDF and must be created and coded by the user to accept the full array and another array holding the selected rows as parameters. The button is disabled if no function is specified. - Exit script - Exit the script immediately. ###Related### ###Example### @@IncludeExample@@
    1 point
  3. BrewManNH

    MsgBox Problem

    Too many quotes try this. Func _MsgBoxEx($iFlag, $sTitle, $sText) Run(@AutoItExe & ' /AutoIt3ExecuteLine "MsgBox(' & $iFlag & ',' & "'" & $sTitle & "'" &',' & "'" & $sText & "'" & ')"') EndFunc
    1 point
  4. jdelaney

    MsgBox Problem

    _MsgBoxEx(1,"test","message") Func _MsgBoxEx($iFlag, $sTitle, $sText) Run(@AutoItExe & ' /AutoIt3ExecuteLine "MsgBox(""' & $iFlag & '"",""' & $sTitle & '"",""' & $sText & '"")"') EndFunc
    1 point
  5. HawkySoft, If you are trying to change an existing item use _GUICtrlListView_SetItemText. edit: Also, use an array as shown in Xeno's example. It will save you headaches later.
    1 point
  6. BrewManNH

    Problem - UserCreator

    I gave you 2.
    1 point
  7. Don't bump, you should know this by now. Why not try isolating the issue first by not using the Google Maps UDF and then work from there. As I hope you can appreciate, it's quite difficult to fix a problem in an entire program that you've designed yourself. I hope you will put your acquired debugging skills to some use. PS You didn't mention the essentials of what system you're using. PPS From what I can see you have just merged a bunch of code together hoping it will work. As you can see that's an improper way to code a program, especially if you don't understand the code you're adding.
    1 point
  8. Hi, In AutoIT, we use & to join string instead of + So: GUICreate ( "Stats " + $version, 850, 500 ) should be: GUICreate ( "Stats " & $version, 850, 500 ) Note: untested
    1 point
  9. I suppose you were trying to do something like this GUICreate("listview items", 220, 250, 100, 200) $listview = GUICtrlCreateListView("col1 |col2", 10, 10, 200, 150) GUISetState() For $i = 0 To 9 Assign("item" & $i, GUICtrlCreateListViewItem($i & '|' & @UserName , $listview) ) Next Msgbox(0,"", GUICtrlRead($item5)) Msgbox(0,"", GUICtrlRead(Eval("item6"))) But Xenobiologist's solution using an array is by far a much better one
    1 point
  10. LarsJ

    The Shell Context Menu

    See original post dated 2012-09-12 below. Final release: 2012-10-10 Everything put together in one zipfile (bottom of post) with two UDFs: ShellContextMenu.au3 and ShellContextMenuCustom.au3. The zip contains several examples. If you use ShellContextMenuCustom to add custom items to the context menu or modify existing items you must include five functions in your program to handle the custom/modified items: InsertCustomMenuItems(), InvokeCustomMenuItems(), HelpOnCustomMenuItems(), PrintMenuHelpMessage() and WM_INITMENUPOPUP(). See ListViewCustom. To add bitmaps to custom menu items you need _GUICtrlMenu_CreateBitmap.au3 and/or GUICtrlMenuEx.au3. See update #2. You also need APIConstants.au3 v3.8. Examples All examples are based on a ListView. Drag and drop some files or folders on the ListView. ListView.au3: Small example with ShellContextMenu.au3. ListViewCustom.au3: An example with ShellContextMenuCustom.au3. Shows how to add custom items to the context menu and how to add bitmaps to the custom items. ExContextMenus.au3: Shows three different context menus. If you right click a file/folder it shows the usual menu. If you right click in the free area of the ListView it shows a context menu similar to the context menu in the free area of Windows Explorer. This menu contains the New-menu. If you right click a label in the bottom of the GUI it shows the desktop context menu. ExModifyMenu.au3: Shows how to add custom items to the context menu and modify existing items. Also shows how to add bitmaps to custom items and to identify existing items with the language-independent verb. The picture is created from this example. ExPrintMenu.au3: If you right click a file/folder to display the menu and then quit, info about the menu items will be printed with _ArrayDisplay(). For each item the index, command id, menu text and verb will be printed. ExSubmenu.au3: Adds the context menu to an existing menu as a submenu. Update #7 2012-10-08: Cut/Copy/Paste asdf8 has pointed out that Cut/Copy/Paste commands aren't working. I've been doing some reading on this subject in the weekend. To make Cut/Copy/Paste work just use OleInitialize() to initialize COM in stead of CoInitialize(). Zipfile updated. Update #6 2012-10-05: Multiple selections asdf8 has pointed out that the menu commands aren't working if more than one file/folder is selected in the ListView. If this line in ShellContextMenu.au3 and ShellContextMenuCustom.au3: If $IShellFolder.GetUIObjectOf( $NULL, 1, $tArray, $tRIID_IContextMenu, 0, $pIContextMenu ) = $S_OK Then is replaced with this line: If $IShellFolder.GetUIObjectOf( $NULL, $cidl, $apidl, $tRIID_IContextMenu, 0, $pIContextMenu ) = $S_OK Then where $cidl is the number of selected files/folders and $apidl is an array of PIDLs for the files/folders relative to the parent folder, then the menu commands are working for multiple selections. Changed the styles of ListViews to allow multiple selections. Zipfile updated. Update #5 2012-10-01 Not applicable after update #6: Changed the style of ListViewCustom.au3 to allow multiple selections and added an example to show the proper Properties dialog box when multiple files/folders are selected. This is done with the function SHMultiFileProperties and the helper function CIDLData_CreateFromIDArray. Both functions are implemented in shell32.dll. On XP CIDLData_CreateFromIDArray can only be called with the ordinal value which is 83. Fixed an error in ListViewCustom.au3 which could lead to a crash on Windows 7. The function GetCommandVerb( $iCmd ) to get the language-independent verb must not be called if not $iCmd is in the valid range between $idCmdFirst (0x0001) and $idCmdLast (0x6FFF). Update #4 2012-09-27: Language-independent verb Added the CMF_EXTENDEDVERBS flag to the QueryContextMenu method to get extended items (Pin to Start menu) if holding the shift key while right clicking. To modify existing menu items it's necessary to be able to identify the items. A convenient way to identify the items is to use the language-independent verb. The language-independent verb can be extracted with a function like this: ; Get the verb, the language-independent command name ; Canonical verbs: copy, cut, delete, open, paste, print, rename Func GetCommandVerb( $iCmd ) Local $uFlags, $szName, $pszName, $tszName $uFlags = $GCS_VERB $tszName = DllStructCreate( "wchar[64]" ) $pszName = DllStructGetPtr( $tszName, 1 ) If $IContextMenu.GetCommandString( $iCmd - $idCmdFirst, $uFlags, $NULL, $pszName, 64 ) = $S_OK Then If BitAND( $uFlags, $GCS_UNICODE ) Then $szName = DllStructGetData( $tszName, 1 ) If StringLen( $szName ) > 0 Then Return $szName EndIf EndIf Return "" EndFuncGetCommandVerb() is called from WM_INITMENUPOPUP(). The WM_INITMENUPOPUP message is catched in the new window procedure. Examples of these canonical verbs are: copy, cut, delete, open, paste, print and rename. In ListViewCustom the Cut/Copy commands are renamed to Copy/Paste, the command identifiers are saved in two variables, and custom code is executed in stead of the default code. Update #3 2012-09-23: Help messages For Windows Explorer under XP help messages for the context menu are shown in the status bar. A help message is shown when an item is selected (hilited). When an item is selected it generates a WM_MENUSELECT notification which can be catched in the new window procedure: ; New window procedure to be able to handle messages from the shell context menu Func NewWindowProc( $hWnd, $iMsg, $iwParam, $ilParam ) If $pIContextMenu Then If $iMsg = $WM_MENUSELECT Then WM_MENUSELECT( $hWnd, $iMsg, $iwParam, $ilParam ) ... EndFuncIn the WM_MENUSELECT() function help messages are printed with the GetCommandString method of the IContextMenu interface. Update #2 2012-09-20: Bitmaps To add bitmaps to system-drawn (not owner-drawn) menu items (Custom1 and Custom2) you can use the UDF _GUICtrlMenu_CreateBitmap.au3 by UEZ. You can get it in the German forum by following this link: http://www.autoit.de/index.php?page=Thread&threadID=21001. The UDF is not included in the zip. To add bitmaps to owner-drawn menu items (Custom3, Custom4 and Custom5) you can use the UDF GUICtrlMenuEx.au3 by Ward. You can get it here: http://www.autoitscript.com/forum/index.php?showtopic=123223. The UDF is not included in the zip. If you want slightly more space between the owner-drawn menu items you can modify a line in the __GUICtrlMenuEx_WM_MEASUREITEM() function like this: DllStructSetData($MeasureItem, "itemHeight", $Size[1]) The original line DllStructSetData($MeasureItem, "itemHeight", $Size[1]+4) Add 4 extra pixels of spaceThis is done in the picture. Added a new zip at the bottom. Update #1 2012-09-17: Custom menu items When we have a handle to the context menu it's easy to add custom items. The zip at the bottom is updated. 2012-09-12 With ObjCreateInterface() it's possible to create a Shell Context Menu (Windows Explorer right click menu) for files and folders e.g. in a ListView or TreeView. This can also be implemented with AutoItObject or with a C/C++ dll-file (there is an example of that in this forum). Here is used ObjCreateInterface() so this is pure AutoIt. To create a Shell Context Menu you use the GetUIObjectOf method of the IShellFolder interface to get a pointer for the IContextMenu interface. With the QueryContextMenu method of this interface you add commands to the context menu and you execute the selected command with the InvokeCommand method. With QueryInterface you can get pointers to the IContextMenu2 and IContextMenu3 interfaces. You need these interfaces to be able to handle owner-drawn menu items e.g. the "Open With" or "Send To" submenues. To handle the events of the owner-drawn menu items you also need a new window procedure and you must initialize COM. This is the function in the UDF that shows the context menu: ; Show the Shell Context Menu Func ShellContextMenu( $hWnd, $hWndContext, $tPOINT, $sFullPath ) Local $pidlFQ, $pidlRel, $pIShellFolder, $IShellFolder Local $pIContextMenu, $IContextMenu, $tArray = DllStructCreate( "ptr" ) Local $hPopup, $iX, $iY, $iCmd, $fMask, $KeyState ; Get the fully qualified PIDL associated with the file $pidlFQ = ILCreateFromPath( $sFullPath ) ; Get an IShellFolder interface pointer ($pIShellFolder) for the parent folder ; and a PIDL ($pidlRel) associated with the file relative to the parent folder. SHBindToParent( $pidlFQ, DllStructGetPtr( $tRIID_IShellFolder ), $pIShellFolder, $pidlRel ) ; Create an IDispatch-Object for the IShellFolder Interface $IShellFolder = ObjCreateInterface( $pIShellFolder, $sIID_IShellFolder, $dtagIShellFolder ) ; Get a pointer to the IContextMenu Interface DllStructSetData( $tArray, 1, $pidlRel ) If $IShellFolder.GetUIObjectOf( $NULL, 1, $tArray, $tRIID_IContextMenu, 0, $pIContextMenu ) = $S_OK Then ; Create an IDispatch-Object for the IContextMenu Interface $IContextMenu = ObjCreateInterface( $pIContextMenu, $sIID_IContextMenu, $dtagIContextMenu ) ; Create a Popup menu $hPopup = CreatePopupMenu() ; Add commands to the Popup menu $IContextMenu.QueryContextMenu( $hPopup, 0, $idCmdFirst, $idCmdLast, $CMF_NORMAL ) ; Create an IDispatch-Object for the IContextMenu2 Interface $IContextMenu.QueryInterface( DllStructGetPtr( $tRIID_IContextMenu2 ), $pIContextMenu2 ) $IContextMenu2 = ObjCreateInterface( $pIContextMenu2, $sIID_IContextMenu2, $dtagIContextMenu2 ) ; Create an IDispatch-Object for the IContextMenu3 Interface $IContextMenu.QueryInterface( DllStructGetPtr( $tRIID_IContextMenu3 ), $pIContextMenu3 ) $IContextMenu3 = ObjCreateInterface( $pIContextMenu3, $sIID_IContextMenu3, $dtagIContextMenu3 ) ; Convert client coordinates to screen coordinates. ; This is among other things used to place the upper left corner ; of the Properties dialog box at the position of the mouse cursor. _WinAPI_ClientToScreen( $hWndContext, $tPoint ) $iX = DllStructGetData( $tPoint, "X" ) $iY = DllStructGetData( $tPoint, "Y" ) ; Show the Popup menu and track the selection $iCmd = TrackPopupMenuEx( $hPopup, $TPM_RETURNCMD, $iX, $iY, $hWnd ) If $iCmd > 0 Then ; Create and fill a $tagCMINVOKECOMMANDINFOEX structure Local $tCMINVOKECOMMANDINFOEX = DllStructCreate( $tagCMINVOKECOMMANDINFOEX ) DllStructSetData( $tCMINVOKECOMMANDINFOEX, "cbSize", DllStructGetSize( $tCMINVOKECOMMANDINFOEX ) ) $fMask = BitOr( $CMIC_MASK_UNICODE, $CMIC_MASK_PTINVOKE ) $KeyState = GetKeyState( $VK_CONTROL ) If $KeyState < 0 Or $KeyState > 32768 Then _ $fMask = BitOr( $fMask, $CMIC_MASK_CONTROL_DOWN ) $KeyState = GetKeyState( $VK_SHIFT ) If $KeyState < 0 Or $KeyState > 32768 Then _ $fMask = BitOr( $fMask, $CMIC_MASK_SHIFT_DOWN ) DllStructSetData( $tCMINVOKECOMMANDINFOEX, "fMask", $fMask ) DllStructSetData( $tCMINVOKECOMMANDINFOEX, "hWnd", $hWnd ) DllStructSetData( $tCMINVOKECOMMANDINFOEX, "lpVerb", $iCmd - $idCmdFirst ) DllStructSetData( $tCMINVOKECOMMANDINFOEX, "lpVerbW", $iCmd - $idCmdFirst ) DllStructSetData( $tCMINVOKECOMMANDINFOEX, "nShow", $SW_SHOWNORMAL ) DllStructSetData( $tCMINVOKECOMMANDINFOEX, "X", $iX ) DllStructSetData( $tCMINVOKECOMMANDINFOEX, "Y", $iY ) ; Invoke the command $IContextMenu.InvokeCommand( $tCMINVOKECOMMANDINFOEX ) EndIf ; Free memory allocated by the PIDL CoTaskMemFree( $pidlFQ ) ; Destroy menu and free memory DestroyMenu( $hPopup ) $pIContextMenu3 = 0 $pIContextMenu2 = 0 $IContextMenu3 = 0 $IContextMenu2 = 0 $IContextMenu = 0 $IShellFolder = 0 EndIf EndFunc Double click To open a file or folder in Windows Explorer you double click it. It's the same as right click and select the default (bold) menu item. When you double click you use the CMF_DEFAULTONLY flag to tell the QueryContextMenu that you only want the default menu item. This is the function in the UDF that executes the default menu item: ; Execute the default menu item Func InvokeCommand( $hWnd, $sFullPath ) Local $pidlFQ, $pidlRel, $pIShellFolder, $IShellFolder Local $pIContextMenu, $IContextMenu, $tArray = DllStructCreate( "ptr" ) Local $hPopup, $aRet, $idMenu ; Get the fully qualified PIDL associated with the file $pidlFQ = ILCreateFromPath( $sFullPath ) ; Get an IShellFolder interface pointer ($pIShellFolder) for the parent folder ; and a PIDL ($pidlRel) associated with the file relative to the parent folder. SHBindToParent( $pidlFQ, DllStructGetPtr( $tRIID_IShellFolder ), $pIShellFolder, $pidlRel ) ; Create an IDispatch-Object for the IShellFolder Interface $IShellFolder = ObjCreateInterface( $pIShellFolder, $sIID_IShellFolder, $dtagIShellFolder ) ; Get a pointer to the IContextMenu Interface DllStructSetData( $tArray, 1, $pidlRel ) If $IShellFolder.GetUIObjectOf( $NULL, 1, $tArray, $tRIID_IContextMenu, 0, $pIContextMenu ) = $S_OK Then ; Create an IDispatch-Object for the IContextMenu Interface $IContextMenu = ObjCreateInterface( $pIContextMenu, $sIID_IContextMenu, $dtagIContextMenu ) ; Create a Popup menu $hPopup = CreatePopupMenu() ; Add the default command to the Popup menu $aRet = $IContextMenu.QueryContextMenu( $hPopup, 0, $idCmdFirst, $idCmdLast, $CMF_DEFAULTONLY ) If $aRet >= 0 Then ; Get the menu item identifier Local $idMenu = GetMenuItemID( $hPopup, 0 ) ; Create and fill a $tagCMINVOKECOMMANDINFO structure Local $tCMINVOKECOMMANDINFO = DllStructCreate( $tagCMINVOKECOMMANDINFO ) DllStructSetData( $tCMINVOKECOMMANDINFO, "cbSize", DllStructGetSize( $tCMINVOKECOMMANDINFO ) ) DllStructSetData( $tCMINVOKECOMMANDINFO, "fMask", 0 ) DllStructSetData( $tCMINVOKECOMMANDINFO, "hWnd", $hWnd ) DllStructSetData( $tCMINVOKECOMMANDINFO, "lpVerb", $idMenu - $idCmdFirst ) DllStructSetData( $tCMINVOKECOMMANDINFO, "nShow", $SW_SHOWNORMAL ) ; Invoke the command $IContextMenu.InvokeCommand( $tCMINVOKECOMMANDINFO ) EndIf ; Free memory allocated by the PIDL CoTaskMemFree( $pidlFQ ) ; Destroy menu and free memory DestroyMenu( $hPopup ) $IContextMenu = 0 $IShellFolder = 0 EndIf EndFuncThis is a demonstration of how to use these functions to execute the default menu item when you double click. You can do exactly the same thing in one line with the builtin function ShellExecute(). Example This is a small example with a ListView. Drag and drop some files and folders on the ListView and right click to show the context menu or double click to open. (If the window with the ListView is inactive then activate the window by clicking the titlebar or click in the ListView outside the items. If you click a LV item in an inactive window it generates a double click and opens the corresponding file or folder.) #include <GuiListView.au3> #include <GUIConstantsEx.au3> #include "ShellContextMenu.au3" Opt( "MustDeclareVars", 1 ) Global $hGui, $idLV, $hLV, $idLVdropFiles, $aLVfiles[1] Global $idLVrightClick, $idLVdoubleClick, $tLVpoint, $iLVidx MainScript() Func MainScript() $hGui = GUICreate( "The Shell Context Menu", 300, 200, 600, 300, -1, BitOR( $WS_EX_ACCEPTFILES, $WS_EX_TOPMOST ) ) $idLV = GUICtrlCreateListView( "", 0, 0, 300, 200 ) GUICtrlSetStyle( $idLV, BitOR( $LVS_LIST, $GUI_SS_DEFAULT_LISTVIEW ) ) GUICtrlSetState( $idLV, $GUI_DROPACCEPTED ) $hLV = ControlGetHandle( $hGui, "", $idLV ) $idLVdropFiles = GUICtrlCreateDummy() $idLVrightClick = GUICtrlCreateDummy() $idLVdoubleClick = GUICtrlCreateDummy() ; Window Procedures $hNewWinProc = DllCallbackRegister( "NewWindowProc", "int", "hwnd;uint;wparam;lparam" ) ; New window procedure $hOldWinProc = _WinAPI_SetWindowLong( $hGui, $GWL_WNDPROC, DllCallbackGetPtr( $hNewWinProc ) ) ; Old window procedure GUIRegisterMsg( $WM_DROPFILES, "WM_DROPFILES" ) GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) GUISetState( @SW_SHOW ) ; Initialize COM CoInitialize() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete( $hGui ) ; Cleanup DllCallbackFree( $hNewWinProc ) CoUninitialize() CloseDlls() Exit Case $idLVdropFiles LVupdate() Case $idLVrightClick ; Show the Shell Context Menu ShellContextMenu( $hGui, $hLV, $tLVpoint, $aLVfiles[$iLVidx] ) Case $idLVdoubleClick ; Execute the default menu item InvokeCommand( $hGui, $aLVfiles[$iLVidx] ) EndSwitch WEnd EndFunc Func WM_DROPFILES( $hWnd, $iMsg, $iwParam, $ilParam ) #forceref $iMsg, $ilParam Switch $hWnd Case $hGui Local $aRet, $nSize, $tFileName $aRet = DllCall( $dllShell32, "int", "DragQueryFile", "hwnd", $iwParam, "int", -1, "ptr", 0, "int", 255 ) For $i = 0 To $aRet[0] - 1 $nSize = DllCall( $dllShell32, "int", "DragQueryFile", "hwnd", $iwParam, "int", $i, "ptr", 0, "int", 0 ) $nSize = $nSize[0] + 1 $tFileName = DllStructCreate( "char[" & $nSize & "]" ) DllCall( $dllShell32, "int", "DragQueryFile", "hwnd", $iwParam, "int", $i, "ptr", DllStructGetPtr( $tFileName ), "int", $nSize ) ReDim $aLVfiles[$i+1] $aLVfiles[$i] = DllStructGetData( $tFileName, 1 ) $tFileName = 0 Next GUICtrlSendToDummy( $idLVdropFiles ) Return 0 EndSwitch EndFunc Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam Local $tNMHDR, $hWndFrom, $iCode $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hLV Switch $iCode Case $NM_DBLCLK $tLVpoint = _WinAPI_GetMousePos( True, $hLV ) Local $iX = DllStructGetData( $tLVpoint, "X" ) Local $iY = DllStructGetData( $tLVpoint, "Y" ) Local $aHit = _GUICtrlListView_HitTest( $hLV, $iX, $iY ) If $aHit[2] Or $aHit[3] Then $iLVidx = $aHit[0] GUICtrlSendToDummy( $idLVdoubleClick ) EndIf Case $NM_RCLICK $tLVpoint = _WinAPI_GetMousePos( True, $hLV ) Local $iX = DllStructGetData( $tLVpoint, "X" ) Local $iY = DllStructGetData( $tLVpoint, "Y" ) Local $aHit = _GUICtrlListView_HitTest( $hLV, $iX, $iY ) If $aHit[2] Or $aHit[3] Then $iLVidx = $aHit[0] GUICtrlSendToDummy( $idLVrightClick ) Return 0 EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Func LVupdate() _GUICtrlListView_DeleteAllItems( $hLV ) For $file In $aLVfiles GUICtrlCreateListViewItem( StringRight( $file, StringLen( $file ) - StringInStr( $file, "\", 0, -1 ) ), $idLV ) Next EndFuncThe example is also contained in the zipfile. Zipfile The zipfile contains the ShellContextMenu.au3 and ShellContextMenuCustom.au3 UDFs with the necessary globals, structures, interface definitions and functions. You need APIConstants.au3 v3.8 by Yashied. The zip contains several examples too. Testet on XP and 7. It would be nice if someone would test the UDF on Vista. The zipfile can be opened with 7-Zip. ShellContextMenu.zip (You need _GUICtrlMenu_CreateBitmap.au3 and/or GUICtrlMenuEx.au3. See top of post.)
    1 point
×
×
  • Create New...