Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 10/08/2018 in all areas

  1. Strydr, We do not just write scripts to order - we help you get your script running as you wish. Think of the old saying: "Give a man a fish, you feed him for a day; give a man a net and you feed him forever". We try to be net makers and repairers, not fishmongers. So I suggest not holding your breath awaiting a response - although if anyone is feeling generous you might be lucky..... M23
    1 point
  2. IonGoG Wishlist has been updated to v0.0_b17, see first post. Recent changes at GOG meant that price was missing from the source, but using the _IECreate function rather than _InetRead, allowed enough time for some of the On Load JavaScript to run, which includes the Price. This is only the second time I have used IECreate, that I can recall. Thanks to TheDcoder for suggesting I use it. The trade-off, is things are now slower for ADD Game and Price QUERY. (v0.0_b17) More Game Detail is auto-detected and better processed, perhaps avoiding manual editing. THANKS to TheDcoder for suggesting I use a hidden IE instance instead, to get the price. BUGFIX for ADD duplicate entry when Cancel is selected. BUGFIX for moving an entry to another User, using the Menu entry method (instead of Accelerator Key). (v0.0_b16) Auto-detecting the price has been restored by using IE browser functions. Query the price for a single item, will now display a Details window, that can be used to update various elements for an entry. The Details window always displays for ADD, after any automation has finished. NOTE - User can manually copy various details from the Game web page, then paste them into the Details window, to modify existing or add any that are missing. (v0.0_b15) Auto-detecting the price is broken by recent GOG layout changes to their web pages, so a few manual prompt queries have been added, for both the ADD and Price QUERY processes, which also provide greater control over the previous detail extraction method and the input/save process. NOTE - Future updates may improve things more. Screenshot is a new GUI addition for ADD and QUERY, which allows for manual editing.
    1 point
  3. @argumentum Great idea! I have added the following .vbs codes to the scrubber exit script so I can watch for the file creation. Testing and will report back. sTmp = "ReturnErrorOrSuccess switch has been set. The current value return code translates to: " If fOverallSuccess Then outFile="C:\Clean\Install\Success.txt" Set objFile = objFSO.CreateTextFile(outFile,True) objFile.Write "No restart required." & vbCrLf objFile.Close iError = ERROR_SUCCESS Log sTmp & "SUCCESS" Else Log sTmp & "ERROR" End If End If ' Reboot handling If fRebootRequired Then outFile="C:\Clean\Install\Restart.txt" Set objFile = objFSO.CreateTextFile(outFile,True) objFile.Write "Restart required." & vbCrLf objFile.Close sPrompt = "In order to complete uninstall, a system reboot is necessary. Would you like to reboot now?" If NOT fQuiet Then If MsgBox(sPrompt, vbYesNo, SCRIPTNAME & " - Reboot Required") = VB_YES Then Dim colOS, oOS Dim oWmiReboot Set oWmiReboot = GetObject("winmgmts:{impersonationLevel=impersonate,(Shutdown)}!\\.\root\cimv2") Set colOS = oWmiReboot.ExecQuery ("Select * from Win32_OperatingSystem") For Each oOS in colOS oOS.Reboot() Next End If End If End If wscript.quit iError End Sub 'ExitScript
    1 point
  4. In GUIRegisterMsg20 - Subclassing Made Easy we saw that it's possible to execute too much code in the WM_NOTIFY message handler in ListView1.au3: Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData ) ; $iSubclassId = 0, $pData = 0 If $iMsg <> $WM_NOTIFY Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] Local Static $tText = DllStructCreate( "wchar[100]" ), $pText = DllStructGetPtr( $tText ) Local Static $tRect = DllStructCreate( $tagRECT ), $pRect = DllStructGetPtr( $tRect ) Switch DllStructGetData( DllStructCreate( $tagNMHDR, $lParam ), "Code" ) Case $LVN_GETDISPINFOW ; Fill virtual listview Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam ) If Not BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then Return Local $sItem = $aItems[DllStructGetData($tNMLVDISPINFO,"Item")][DllStructGetData($tNMLVDISPINFO,"SubItem")] DllStructSetData( $tText, 1, $sItem ) DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) ) DllStructSetData( $tNMLVDISPINFO, "Text", $pText ) Return Case $NM_CUSTOMDRAW ; Draw back colors Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" ), $iItem Switch $dwDrawStage ; Holds a value that specifies the drawing stage Case $CDDS_PREPAINT ; Before the paint cycle begins Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any item-related drawing operations Case $CDDS_ITEMPREPAINT ; Before painting an item Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window of any subitem-related drawing operations Case $CDDS_ITEMPREPAINT + $CDDS_SUBITEM ; Before painting a subitem $iItem = DllStructGetData( $tNMLVCUSTOMDRAW, "dwItemSpec" ) If GUICtrlSendMsg( $idListView, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED ) Then Return $CDRF_NOTIFYPOSTPAINT ; Selected item DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", $aColors[$iItem][DllStructGetData($tNMLVCUSTOMDRAW,"iSubItem")] ) ; Normal item Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors Case $CDDS_ITEMPOSTPAINT + $CDDS_SUBITEM ; After painting a subitem Local $hDC = DllStructGetData( $tNMLVCUSTOMDRAW, "hdc" ) ; Subitem rectangle $iItem = DllStructGetData( $tNMLVCUSTOMDRAW, "dwItemSpec" ) Local $iSubItem = DllStructGetData( $tNMLVCUSTOMDRAW, "iSubItem" ) DllStructSetData( $tRect, "Left", $LVIR_LABEL ) DllStructSetData( $tRect, "Top", $iSubItem ) GUICtrlSendMsg( $idListView, $LVM_GETSUBITEMRECT, $iItem, $pRect ) DllStructSetData( $tRect, "Left", DllStructGetData( $tRect, "Left" ) + 2 ) DllStructSetData( $tRect, "Top", DllStructGetData( $tRect, "Top" ) + 1 ) DllStructSetData( $tRect, "Right", DllStructGetData( $tRect, "Right" ) - 2 ) DllStructSetData( $tRect, "Bottom", DllStructGetData( $tRect, "Bottom" ) - 1 ) ; Subitem back color Local $hBrush = DllCall( "gdi32.dll", "handle", "CreateSolidBrush", "int", $aColors[$iItem][$iSubItem] )[0] ; _WinAPI_CreateSolidBrush DllCall( "user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $tRect, "handle", $hBrush ) ; _WinAPI_FillRect DllCall( "gdi32.dll", "bool", "DeleteObject", "handle", $hBrush ) ; _WinAPI_DeleteObject ; Draw subitem text DllStructSetData( $tRect, "Top", DllStructGetData( $tRect, "Top" ) + 1 ) DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int", 0 ) ; _WinAPI_SetTextColor DllCall( "gdi32.dll", "int", "SetBkMode", "handle", $hDC, "int", $TRANSPARENT ) ; _WinAPI_SetBkMode DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aItems[$iItem][$iSubItem], "int", -1, "struct*", $tRect, "uint", $DT_CENTER ) ; _WinAPI_DrawText Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch EndSwitch Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $hWnd, $iMsg, $wParam, $iSubclassId, $pData EndFunc The code here is a full subclass implementation (not based on the UDF). You can provoke the error this way: Click a row in the listview (not one of the very top rows). Press Shift+Down arrow to select multiple rows. The problem will arise after just a few rows. Press Ctrl+Break in SciTE to stop the code. One way to make the code faster is to use compiled code. Let's take a closer look at the subclass implementation: Local $pWM_NOTIFY = DllCallbackGetPtr( DllCallbackRegister( "WM_NOTIFY", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) DllCall( "comctl32.dll", "bool", "SetWindowSubclass", "hwnd", $hGui, "ptr", $pWM_NOTIFY, "uint_ptr", 0, "dword_ptr", 0 ) ; $iSubclassId = 0, $pData = 0 $pWM_NOTIFY is a pointer to the message handler function. To replace the AutoIt message handler with compiled code, we can implement the message handler in C/C++ code in a dll-file and replace $pWM_NOTIFY with a pointer to the compiled code. The C/C++ function definition looks like this: LRESULT CALLBACK __stdcall MsgHandler( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) We can get a pointer to the message handler this way: Local $hModule = _WinAPI_LoadLibrary( "Subclass.dll" ) Local $pMsgHandler = _WinAPI_GetProcAddress( $hModule, "MsgHandler" ) Now we can simply replace $pWM_NOTIFY with $pMsgHandler in SetWindowSubclass function. And of course we need to pass the $aItems and $aColors arrays to the compiled code in the dll-file. But we already know how to do that. Note that because $pMsgHandler is used directly in SetWindowSubclass function, we can avoid both the DllCall and DllCallAddress commands. Thus, we avoid a severe overhead in relation to these commands (that the AutoIt code interpreter should interpret a code line for each message (for a huge number of messages), and that DllCall and DllCallAddress are complicated and time-consuming commands). AutoIt code in ListView2.au3: #include <GUIConstantsEx.au3> #include "GuiListViewEx.au3" #include "AccArrays.au3" Opt( "MustDeclareVars", 1 ) Global $apsa[2] ; $psaItems, $psaColors Example() Func Example() ; Rows and columns Local $iRows = 10000, $iCols = 8 ; Create GUI Local $hGui = GUICreate( "Virtual and Custom Drawn ListView", 820, 620 ) ; Create ListView Local $idListView = GUICtrlCreateListView( "", 10, 10, 800, 600, $GUI_SS_DEFAULT_LISTVIEW+$LVS_OWNERDATA-$LVS_SINGLESEL ) _GUICtrlListView_SetExtendedListViewStyle( $idListView, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT ) Local $hListView = GUICtrlGetHandle( $idListView ) ; Add columns For $i = 0 To $iCols - 1 _GUICtrlListView_AddColumn( $idListView, "Col " & $i, 96, 2 ) Next ; ListView items Local $aItems[$iRows][$iCols] For $i = 0 To $iRows - 1 For $j = 0 To $iCols - 1 $aItems[$i][$j] = $i & "/" & $j Next Next ; ListView colors Local $aColors[$iRows][$iCols] Local $aLVColors = [ 0xCCCCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFFCC, 0xFFCCCC, 0xFFCCFF ] ; BGR For $i = 0 To $iRows - 1 For $j = 0 To $iCols - 1 $aColors[$i][$j] = $aLVColors[Random( 0,5,1 )] Next Next ; Load dll-file Local $hDll = DllOpen( @AutoItX64 ? "Subclass_x64.dll" : "Subclass.dll" ) Local $hModule = _WinAPI_LoadLibrary( @AutoItX64 ? "Subclass_x64.dll" : "Subclass.dll" ) ; $aItems and $aColors Local $psaItemsData, $psaColorsData AccArrays02( SafeArrays, $aItems, $aColors ) SafeArrayAccessData( $apsa[0], $psaItemsData ) SafeArrayAccessData( $apsa[1], $psaColorsData ) ; Pass data to compiled code DllCall( $hDll, "none", "PassData", "hwnd", $hListView, "int", $iCols, "ptr", $psaItemsData, "ptr", $psaColorsData ) ; Register WM_NOTIFY message handler Local $pMsgHandler = _WinAPI_GetProcAddress( $hModule, "MsgHandler" ) DllCall( "comctl32.dll", "bool", "SetWindowSubclass", "hwnd", $hGui, "ptr", $pMsgHandler, "uint_ptr", 0, "dword_ptr", 0 ) ; $iSubclassId = 0, $pData = 0 ; Set number of rows in virtual ListView GUICtrlSendMsg( $idListView, $LVM_SETITEMCOUNT, $iRows, 0 ) ; Adjust height of GUI and ListView to fit 30 rows Local $iLvHeight = _GUICtrlListView_GetHeightToFitRows( $idListView, 30 ) WinMove( $hGui, "", Default, Default, Default, WinGetPos( $hGui )[3] - WinGetClientSize( $hGui )[1] + $iLvHeight + 20 ) WinMove( GUICtrlGetHandle( $idListView ), "", Default, Default, Default, $iLvHeight ) ; Show GUI GUISetState( @SW_SHOW ) ; Message loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_RESTORE ; Adjust height of GUI and ListView to fit 30 rows $iLvHeight = _GUICtrlListView_GetHeightToFitRows( $idListView, 30 ) WinMove( $hGui, "", Default, Default, Default, WinGetPos( $hGui )[3] - WinGetClientSize( $hGui )[1] + $iLvHeight + 20 ) WinMove( GUICtrlGetHandle( $idListView ), "", Default, Default, Default, $iLvHeight ) Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup DllCall( "comctl32.dll", "bool", "RemoveWindowSubclass", "hwnd", $hGui, "ptr", $pMsgHandler, "uint_ptr", 0 ) ; $iSubclassId = 0 SafeArrayUnaccessData( $apsa[0] ) SafeArrayUnaccessData( $apsa[1] ) _WinAPI_FreeLibrary( $hModule ) DllClose( $hDLL ) GUIDelete() EndFunc Func SafeArrays( $pvItems, $pvColors ) SafeArrayCopy( DllStructGetData( DllStructCreate( "ptr", $pvItems + 8 ), 1 ), $apsa[0] ) SafeArrayCopy( DllStructGetData( DllStructCreate( "ptr", $pvColors + 8 ), 1 ), $apsa[1] ) EndFunc C/C++ code in Subclass.cpp: #include <Windows.h> #include <CommCtrl.h> #include <OleAuto.h> // Globals HWND g_hListView; int g_iColumns; VARIANT* g_psaItems; VARIANT* g_psaColors; void __stdcall PassData( HWND hListView, int iColumns, VARIANT* psaItems, VARIANT* psaColors ) { g_hListView = hListView; g_iColumns = iColumns; g_psaItems = psaItems; g_psaColors = psaColors; } LRESULT CALLBACK __stdcall MsgHandler( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) { if ( uMsg != WM_NOTIFY ) return DefSubclassProc( hWnd, uMsg, wParam, lParam ); NMLVDISPINFOW* plvdi; NMLVCUSTOMDRAW* plvcd; BSTR pBstr; DWORD_PTR iItem; RECT r; HBRUSH hBrush; switch ( ((LPNMHDR)lParam)->code ) { case LVN_GETDISPINFOW: // Fill virtual listview plvdi = (NMLVDISPINFOW*)lParam; if ( ( plvdi->item.mask & LVIF_TEXT ) == 0 ) return TRUE; pBstr = g_psaItems[plvdi->item.iItem*g_iColumns+plvdi->item.iSubItem].bstrVal; plvdi->item.pszText = pBstr; plvdi->item.cchTextMax = SysStringLen( pBstr ); return TRUE; case NM_CUSTOMDRAW: // Draw back colors plvcd = (NMLVCUSTOMDRAW*)lParam; switch ( plvcd->nmcd.dwDrawStage ) { case CDDS_PREPAINT: return CDRF_NOTIFYITEMDRAW; case CDDS_ITEMPREPAINT: return CDRF_NOTIFYSUBITEMDRAW; case CDDS_ITEMPREPAINT | CDDS_SUBITEM: iItem = plvcd->nmcd.dwItemSpec; if ( SendMessageW( g_hListView, LVM_GETITEMSTATE, iItem, LVIS_SELECTED ) ) return CDRF_NOTIFYPOSTPAINT; plvcd->clrTextBk = g_psaColors[iItem*g_iColumns+plvcd->iSubItem].intVal; return CDRF_NEWFONT; case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM: // Subitem rectangle iItem = plvcd->nmcd.dwItemSpec; r.left = LVIR_LABEL; r.top = plvcd->iSubItem; SendMessageW( g_hListView, LVM_GETSUBITEMRECT, iItem, (LPARAM)&r ); r.left += 2; r.right -= 2; r.top += 1; r.bottom -= 1; // Subitem back color hBrush = CreateSolidBrush( g_psaColors[iItem*g_iColumns+plvcd->iSubItem].intVal ); FillRect( plvcd->nmcd.hdc, &r, hBrush ); DeleteObject( hBrush ); // Draw subitem text SetTextColor( plvcd->nmcd.hdc, 0 ); SetBkMode( plvcd->nmcd.hdc, TRANSPARENT ); pBstr = g_psaItems[iItem*g_iColumns+plvcd->iSubItem].bstrVal; r.top += 1; DrawTextW( plvcd->nmcd.hdc, pBstr, SysStringLen( pBstr ), &r, DT_CENTER ); return CDRF_NEWFONT; } } return DefSubclassProc( hWnd, uMsg, wParam, lParam ); } Zip-file ListView1.au3 is pure AutoIt code. In ListView2.au3 the WM_NOTIFY message handler is replaced with compiled code. Note that the zip-file contains two small dll-files. If you are using Microsoft SmartScreen or Microsoft Windows Defender, there is a likelihood of fake virus detection, even if the dll-files are created with Microsoft Visual Studio. Most other antivirus products will not detect fake viruses. You need AutoIt 3.3.12 or later. Tested on Windows 7 and Windows 10. Comments are welcome. Let me know if there are any issues. FastSubclassing.7z
    1 point
  5. water

    GUI design concepts.

    Wouldn't it be nice if there was a screenshot with each example script?
    1 point
  6. It seems the message has still not got through - the 2 eager beavers who posted in this thread got a week off: And a word to the wise - the next one gets a month. M23
    0 points
×
×
  • Create New...