AutoIt _ImageSearch and DllCall failure - dllimport

I am trying to detect an image in a window. The window is BlueStacks App Player. I am using the ImageSearch UDF. Problem is it fails.
$result = DllCall("ImageSearchDLL.dll","str","ImageSearch","int",$x1,"int",$y1,"int",$right,"int",$bottom,"ptr",$findImage)
DllCall() should return an array if successful but returns 1 to indicate failure. I tried x86 and x64 versions of this UDF. This is how I call _ImageSearchArea():
_CaptureRegion()
_ImageSearchArea($gameImage, 0,0,0,500,500, $x, $y, 0)
I have Windows 7 X64. Also x64 AutoIt. The window's resolution is 577x690. This is the UDF I am using:
#include-once
; ------------------------------------------------------------------------------
;
; AutoIt Version: 3.0
; Language: English
; Description: Functions that assist with Image Search
; Require that the ImageSearchDLL.dll be loadable
;
; ------------------------------------------------------------------------------
;===============================================================================
;
; Description: Find the position of an image on the desktop
; Syntax: _ImageSearchArea, _ImageSearch
; Parameter(s):
; $findImage - the image to locate on the desktop
; $tolerance - 0 for no tolerance (0-255). Needed when colors of
; image differ from desktop. e.g GIF
; $resultPosition - Set where the returned x,y location of the image is.
; 1 for centre of image, 0 for top left of image
; $x $y - Return the x and y location of the image
;
; Return Value(s): On Success - Returns 1
; On Failure - Returns 0
;
; Note: Use _ImageSearch to search the entire desktop, _ImageSearchArea to specify
; a desktop region to search
;
;===============================================================================
Func _ImageSearch($findImage,$resultPosition,ByRef $x, ByRef $y,$tolerance)
return _ImageSearchArea($findImage,$resultPosition,0,0,#DesktopWidth,#DesktopHeight,$x,$y,$tolerance)
EndFunc
Func _ImageSearchArea($findImage,$resultPosition,$x1,$y1,$right,$bottom,ByRef $x, ByRef $y, $tolerance)
;MsgBox(0,"asd","" & $x1 & " " & $y1 & " " & $right & " " & $bottom)
if $tolerance>0 then $findImage = "*" & $tolerance & " " & $findImage
$result = DllCall("ImageSearchDLL.dll","str","ImageSearch","int",$x1,"int",$y1,"int",$right,"int",$bottom,"ptr",$findImage)
; If error exit
if $result[0]="0" then return 0
; Otherwise get the x,y location of the match and the size of the image to
; compute the centre of search
$array = StringSplit($result[0],"|")
$x=Int(Number($array[2]))
$y=Int(Number($array[3]))
if $resultPosition=1 then
$x=$x + Int(Number($array[4])/2)
$y=$y + Int(Number($array[5])/2)
endif
return 1
EndFunc
;===============================================================================
;
; Description: Wait for a specified number of seconds for an image to appear
;
; Syntax: _WaitForImageSearch, _WaitForImagesSearch
; Parameter(s):
; $waitSecs - seconds to try and find the image
; $findImage - the image to locate on the desktop
; $tolerance - 0 for no tolerance (0-255). Needed when colors of
; image differ from desktop. e.g GIF
; $resultPosition - Set where the returned x,y location of the image is.
; 1 for centre of image, 0 for top left of image
; $x $y - Return the x and y location of the image
;
; Return Value(s): On Success - Returns 1
; On Failure - Returns 0
;
;
;===============================================================================
Func _WaitForImageSearch($findImage,$waitSecs,$resultPosition,ByRef $x, ByRef $y,$tolerance)
$waitSecs = $waitSecs * 1000
$startTime=TimerInit()
While TimerDiff($startTime) < $waitSecs
sleep(100)
$result=_ImageSearch($findImage,$resultPosition,$x, $y,$tolerance)
if $result > 0 Then
return 1
EndIf
WEnd
return 0
EndFunc
;===============================================================================
;
; Description: Wait for a specified number of seconds for any of a set of
; images to appear
;
; Syntax: _WaitForImagesSearch
; Parameter(s):
; $waitSecs - seconds to try and find the image
; $findImage - the ARRAY of images to locate on the desktop
; - ARRAY[0] is set to the number of images to loop through
; ARRAY[1] is the first image
; $tolerance - 0 for no tolerance (0-255). Needed when colors of
; image differ from desktop. e.g GIF
; $resultPosition - Set where the returned x,y location of the image is.
; 1 for centre of image, 0 for top left of image
; $x $y - Return the x and y location of the image
;
; Return Value(s): On Success - Returns the index of the successful find
; On Failure - Returns 0
;
;
;===============================================================================
Func _WaitForImagesSearch($findImage,$waitSecs,$resultPosition,ByRef $x, ByRef $y,$tolerance)
$waitSecs = $waitSecs * 1000
$startTime=TimerInit()
While TimerDiff($startTime) < $waitSecs
for $i = 1 to $findImage[0]
sleep(100)
$result=_ImageSearch($findImage[$i],$resultPosition,$x, $y,$tolerance)
if $result > 0 Then
return $i
EndIf
Next
WEnd
return 0
EndFunc
$gameImage is an image I want to search for.

$findImage is a string variable, thus the dll call should look like this.
$result = DllCall("ImageSearchDLL.dll","str","ImageSearch","int",$x1,"int",$y1,"int",$right,"int",$bottom,"str",$findImage)

Related

"Attempted assignment to a non-variable" in bash

I'm new to Bash and I've been having issues with creating a script. What this script does is take numbers and add them to a total. However, I can't get total to work.It constantly claims that total is a non-variable despite it being assigned earlier in the program.
error message (8 is an example number being entered)
./adder: line 16: 0 = 0 + 8: attempted assignment to non-variable (error token is "= 0 + 8")
#!/bin/bash
clear
total=0
count=0
while [[ $choice != 0 ]]; do
echo Please enter a number or 0 to quit
read choice
if [[ $choice != 0 ]];
then
$(($total = $total + $choice))
$(($count = $count + 1))
echo Total is $total
echo
echo Total is derived from $count numbers
fi
done
exit 0
Get rid of some of the dollar signs in front of the variable names. They're optional inside of an arithmetic context, which is what ((...)) is. On the left-hand side of an assignment they're not just optional, they're forbidden, because = needs the variable name on the left rather than its value.
Also $((...)) should be plain ((...)) without the leading dollar sign. The dollar sign will capture the result of the expression and try to run it as a command. It'll try to run a command named 0 or 5 or whatever the computed value is.
You can write:
((total = $total + $choice))
((count = $count + 1))
or:
((total = total + choice))
((count = count + 1))
or even:
((total += choice))
((count += 1))

how to configure OOTB "inStockFlag" and "reviewAvgRating" index property as facets

Please help to achieve this. I added these two properties from non facets index property to facet index property in solr.implex file. Run the full indexer ,
added customer review for some of the products and approved the status as well in spite of that these two properties are not showing as facets in storefront.
Please guide me step by step how can I achieve this. I have already wasted 2.5 days to achieve the same.
I am using hybris 6.4
First, run the below Impex form the HAC. Don't forget to change apparel-ukProductType with your Indexed type.
$solrIndexedType=apparel-ukProductType
# Facet properties
INSERT_UPDATE SolrIndexedProperty ; solrIndexedType(identifier)[unique=true] ; name[unique=true] ; type(code) ; sortableType(code) ; currency[default=false] ; localized[default=false] ; multiValue[default=false] ; useForSpellchecking[default=false] ; useForAutocomplete[default=false] ; fieldValueProvider ; valueProviderParameters[map-delimiter=|] ; ftsPhraseQuery[default=false] ; ftsPhraseQueryBoost ; ftsQuery[default=false] ; ftsQueryBoost ; ftsFuzzyQuery[default=false] ; ftsFuzzyQueryBoost ; ftsWildcardQuery[default=false] ; ftsWildcardQueryType(code)[default=POSTFIX] ; ftsWildcardQueryBoost ; ftsWildcardQueryMinTermLength ; facetType(code) ; facetSort(code) ; priority ; visible ; facet[default=true]
; $solrIndexedType ; reviewAvgRating ; double ; ; ; TRUE ; ; ; ; productReviewAverageRatingValueProvider ; ; ; ; ; ; ; ; ; ; ; ; MultiSelectOr ; Custom ; 10000 ; true ;
; $solrIndexedType ; inStockFlag ; boolean ; ; ; ; ; ; ; productInStockFlagValueProvider ; ; ; ; ; ; ; ; ; ; ; ; MultiSelectOr ; Custom ; 10000 ; true ;
You can do the same changes from backoffice/hmc.
Go to System > Facet Search > Indexed Type > select your type from list > Find the inStockFlag under Properties filed > scroll to end (right) to edit inStockFlag properties > In popup go to facet setting tab > Mark Facet to true and edit other fields.
Lastly, run the full indexer.

Hybris faceted search

I have a requirement whereby I have to implement a faceted search,where a user is taken through some questions and suggested a list of products on Hybris.Any approach to help me get started?
Solr supports facet search on its own. Hybris leverages this via the solr configuration. You can manage this through the impex file. There are a lot of fields on SolrIndexedProperty, but I think these are the ones required to control facet search - facet=true, facetType, and facetSort.
INSERT_UPDATE SolrIndexedProperty ; ... facet[default = true] ; facetType(code) ; facetSort(code) ; ...
; ... ; MultiSelectOr ; Alpha ; ...
Here's the full impex statement, in case I missed something.
INSERT_UPDATE SolrIndexedProperty ; solrIndexedType(identifier)[unique = true] ; name[unique = true] ; type(code) ; isAlpha[default = false] ; isNumeric[default = false] ; isAlphaNumeric[default = false] ; sortableType(code) ; currency[default = false] ; localized[default = false] ; multiValue[default = false] ; facet[default = true] ; facetType(code) ; facetSort(code) ; priority ; visible ; useForSpellchecking[default = false] ; useForAutocomplete[default = false] ; fieldValueProvider ; valueProviderParameter ; facetDisplayNameProvider ; customFacetSortProvider ; topValuesProvider ; rangeSets(name) ; displayName ; includeInResponse [default=true]
; yourProductType ; colorFacet ; string ; true ; ; ; ; ; ; ; ; MultiSelectOr ; Alpha ; 7500 ; true ; ; ; colorValueProvider ; ; ; facetNameSortProviderAscending ; defaultTopValuesProvider ; ; "Color" ;false

ADA & GTK => function Get_Text

I want to create a Toplevel window and use this function in it .
There is no example anywhere...
Here the complete description in /usr/share/ada/adainclude/gtkada/gtk-gentry.ads
function Get_Text (The_Entry : access Gtk_Entry_Record) return UTF8_String;
-- Modify the text in the entry.
-- The text is cut at the maximum length that was set when the entry was
-- created.
-- The text replaces the current contents.
For Debian and relatives OS , you can access to the directory after : sudo apt-get install libgtkada2.24.1-dev
I figured out how to use the Get_text function with the Entry .
manuBriot & andlabs =
I also found the Signal in the Entry's package for the reaction when the user press _Enter .
Finally , everything works fine now .
What my program do ?
= Its a window , look exactly like this : http://pix.toile-libre.org/?img=1450777307.png
And , after you write something and press _Enter in the graphical entry , the result is print in command_line .
Simple and useful for begining in GTK language .
WITH Gtk.Main ; USE Gtk.Main ;
WITH Gtk.Window ; USE Gtk.Window ;
WITH Gtk.Enums ; USE Gtk.Enums ;
WITH Gtk.Button ; USE Gtk.Button ;
WITH Gtk.Alignment ; USE Gtk.Alignment ;
WITH Gtk.Box ; USE Gtk.Box ;
WITH Gtk.Gentry; USE Gtk.Gentry;
WITH Ada.text_io; USE Ada.text_io;
WITH Gtk.Widget ; USE Gtk.Widget ;
with Gtk.Handlers;
PROCEDURE prototype IS
-----------------------
-- VARIABLES -- |
----------------------------------------------------------
win : Gtk_window ;
Btn1, Btn2 ,Btn3 : Gtk_Button ;
alignG, alignM ,alignD : Gtk_Alignment ;
Boite : Gtk_VBox ;
Boutons : Gtk_HBox ;
saisie : Gtk_Entry ;
----------------------------------------------------------
--Instanciation package(s) for connexion
----------------------------------------------------------
PACKAGE P_Callback IS NEW Gtk.Handlers.Callback(Gtk_Widget_Record);
USE P_Callback ;
----------------------------------------------------------
-- Handlers (or callbacks) |
----------------------------------------------------------
procedure Stop_Program(Emetteur : access Gtk_Widget_Record'class)
is
PRAGMA Unreferenced (Emetteur);
begin
Main_Quit;
end Stop_Program ;
procedure Handler_text(Ent : access Gtk_Widget_Record'class)
is begin
put_line(get_text(saisie));
end Handler_text ;
-------------------------------------------------
BEGIN
Init ;
----------------
-- NEW -- |
-------------------------------------------------
Gtk_New(win);
Gtk_New(saisie);
Gtk_New(Btn1, "Bouton 1") ;
Gtk_New(Btn2, "Bouton 2") ;
Gtk_New(Btn3, "Bouton 3") ;
Gtk_New(alignG,0.0,1.0,1.0,1.0);
Gtk_New(alignM,0.5,1.0,1.0,1.0);
Gtk_New(alignD,1.0,1.0,1.0,1.0);
Gtk_New_VBox
(Boite, homogeneous => false, Spacing => 0) ;
Gtk_New_HBox
(Boutons, homogeneous => false, Spacing => 0) ;
---------------------------------
-- Add |
---------------------------------
alignG.add(Btn1) ;
alignM.add(Btn2) ;
alignD.add(Btn3) ;
win.Add(Boite);
------------------------------------------
-- Connect |
------------------------------------------
Connect(Widget => win ,
Name => "destroy" ,
Cb => Stop_Program'access);
Connect(Widget => saisie ,
Name => "activate" ,
Cb => Handler_text'access);
------------------------------------------
-- Design Window |
------------------------------------------
Boite.Pack_Start(saisie);
Boite.Pack_Start(Boutons);
Boutons.Pack_Start(alignG);
Boutons.Pack_Start(alignM);
Boutons.Pack_Start(alignD);
win.Set_Default_Size(500,500) ;
win.set_position(Win_Pos_Mouse) ;
-- win.set_opacity(0.7) ;
win.Show_all ;
Main ;
END prototype ;
WITH Gtk.Main ; USE Gtk.Main ;
WITH Gtk.Window ; USE Gtk.Window ;
WITH Gtk.Gentry; USE Gtk.Gentry;
WITH Gtk.Box ; USE Gtk.Box ;
WITH Gtk.Enums ; USE Gtk.Enums ;
Procedure gtkada_get_a_entry is
win : Gtk_window ;
space : Gtk_Entry ;
the_box : Gtk_VBox ;
-- function Get_Text (The_Entry : access Gtk_Entry_Record) return UTF8_String;
-- How to use the function ???
begin
Init ;
Gtk_New(win);
Gtk_New(space);
Gtk_New_VBox
(the_box, homogeneous => false, Spacing => 0) ;
the_box.Pack_Start(space);
win.Add(the_box);
win.Set_Default_Size(300,200) ;
win.set_position(Win_Pos_Center) ;
win.Show_all ;
Main ;
end gtkada_get_a_entry;
All I want to do is use the Get_text function as it is described in the package.
The code I posted is minimal: prints on screen the text entry, but again, it's useless if I cannot use the function.

Why does my script fail to create zip files?

#include <File.au3>
#include <Zip.au3>
#include <Array.au3>
; bad file extensions
Local $extData = "ade|adp|app|asa|ashx|asp|bas|bat|cdx|cer|chm|class|cmd|com|cpl|crt|csh|der|exe|fxp|gadget|hlp|hta|htr|htw|ida|idc|idq|ins|isp|its|jse|ksh|lnk|mad|maf|mag|mam|maq|mar|mas|mat|mau|mav|maw|mda|mdb|mde|mdt|mdw|mdz|msc|msh|msh1|msh1xml|msh2|msh2xml|mshxml|msi|msp|mst|ops|pcd|pif|prf|prg|printer|pst|reg|rem|scf|scr|sct|shb|shs|shtm|shtml|soap|stm|url|vb|vbe|vbs|ws|wsc|wsf|wsh"
Local $extensions = StringSplit($extData, "|")
; What is the root directory?
$rootDirectory = InputBox("Root Directory", "Please enter the root directory...")
archiveDir($rootDirectory)
Func archiveDir($dir)
$goDirs = True
$goFiles = True
; Get all the files under the current dir
$allOfDir = _FileListToArray($dir)
$tmax = UBound($allOfDir)
For $t = 0 To $tmax - 1
Next
Local $countDirs = 0
Local $countFiles = 0
$imax = UBound($allOfDir)
For $i = 0 To $imax - 1
If StringInStr(FileGetAttrib($dir & "\" & $allOfDir[$i]), "D") Then
$countDirs = $countDirs + 1
ElseIf StringInStr(($allOfDir[$i]), ".") Then
$countFiles = $countFiles + 1
EndIf
Next
If ($countDirs > 0) Then
Local $allDirs[$countDirs]
$goDirs = True
Else
$goDirs = False
EndIf
If ($countFiles > 0) Then
Local $allFiles[$countFiles]
$goFiles = True
Else
$goFiles = False
EndIf
$dirCount = 0
$fileCount = 0
For $i = 0 To $imax - 1
If (StringInStr(FileGetAttrib($dir & "\" & $allOfDir[$i]), "D")) And ($goDirs == True) Then
$allDirs[$dirCount] = $allOfDir[$i]
$dirCount = $dirCount + 1
ElseIf (StringInStr(($allOfDir[$i]), ".")) And ($goFiles == True) Then
$allFiles[$fileCount] = $allOfDir[$i]
$fileCount = $fileCount + 1
EndIf
Next
; Zip them if need be in current spot using 'ext_zip.zip' as file name, loop through each file ext.
If ($goFiles == True) Then
$fmax = UBound($allFiles)
For $f = 0 To $fmax - 1
$currentExt = getExt($allFiles[$f])
$position = _ArraySearch($extensions, $currentExt)
If #error Then
MsgBox(0, "Not Found", "Not Found")
Else
$zip = _Zip_Create($dir & "\" & $currentExt & "_zip.zip")
_Zip_AddFile($zip, $dir & "\" & $allFiles[$f])
EndIf
Next
EndIf
; Get all dirs under current DirCopy
; For each dir, recursive call from step 2
If ($goDirs == True) Then
$dmax = UBound($allDirs)
$rootDirectory = $rootDirectory & "\"
For $d = 0 To $dmax - 1
archiveDir($rootDirectory & $allDirs[$d])
Next
EndIf
EndFunc
Func getExt($filename)
$pos = StringInStr($filename, ".")
$retval = StringTrimLeft($filename, $pos - 1)
Return $retval
EndFunc
I have a list of file extensions. This script should go through a directory (and subdirectories), zip up (separate zip files for each extension) all files with those extensions.
Why does it not create zip files?
In the function StringTrimLeft("string", count), count is the number of characters to trim.
$filename = "filename.zip"
$pos = StringInStr($filename, ".") ; $pos will be equal to 9
so...
$retval = StringTrimLeft($filename, $pos + 1); this will remove 10 characters = ip
Two suggestions:
Add MsgBox(0, "Zip", "Got here") inside your If ($currentExt == $extensions[$e]) Then. You should see that you are never getting there.
Related to the above, your getExt function is not returning the correct value for the extension of the file.
UPDATE
You went a little too far with your edit to getExt.
Try this:
Func getExt($filename)
$pos = StringInStr($filename, ".")
$retval = StringTrimLeft($filename, $pos)
Return $retval
EndFunc
UPDATE 2
Regarding your problem where it doesn't process folders beyond the 2nd level, your issue is you are using $rootDirectory in your recursive call where you need to use $dir.
Change the last part of your archiveDir function to this:
; For each dir, recursive call from step 2
If ($goDirs == True) Then
$dmax = UBound($allDirs)
$dir = $dir & "\"
For $d = 0 to $dmax - 1
archiveDir($dir & $allDirs[$d])
Next
EndIf
I tried running your code as is, and sure enough, it failed. I then put a
MsgBox(0, "error", #error & " " & $currentExt)
in the "If #error" block to see if I could find out why it was failing. The result was the #error came back as 6. Looking into the documentation, it says that an error code of 6 means that the value searched for was not found in the array. And then the $currentExt told me it's value was set to ".asp".
The reason it could not be found was because there are no periods in the extension names in the array. If you look closer at the getExt() function, before you were adding 1 to the $position value... and now you are subtracting 1 from the value... Here's an illustration of how StringTrimLeft() works...
$filename = "filename.txt"
$pos = StringInStr($filename, ".") ; $pos will be equal to 9
$retval = StringTrimLeft($filename, $pos + 1); this will remove 10 characters = xt, that's too much.
$retval = StringTrimLeft($filename, $pos - 1); this will remove 8 characters = .txt, that's not enough.
$retval = StringTrimLeft($filename, $pos); this will remove 9 characters = txt, that's juuuuuuust right!
So the solution is to either add "." in front of all of the extensions in your array, or change your getExt() function:
Func getExt($filename)
$pos = StringInStr($filename, ".")
$retval = StringTrimLeft($filename, $pos)
Return $retval
EndFunc
There is one more option you could look into, and that is using the _PathSplit() function found in File.au3, but since your script is so close to working at this point, I wouldn't worry about it, but maybe in the future you could use it instead.
And one last note... After I changed getExt() to drop the ".", your script ran great.

Resources