How do you convert or Abbreviate Numbers in Autohotkey(AHK)? (posting answers made by the autohotkey discord group) - autohotkey

I needed to convert numbers in Autohotkey for a game I'm making and some members of the Autohotkey Discord Group were able to help me out.
In particular vieira and andreas#Nasa:~$ sudo -i each came up with a working solution.
vieira
print(GetFormatedNum(1234567890))
print(GetFormatedNum(1234567))
print(GetFormatedNum(1234))
print(GetFormatedNum(12))
GetFormatedNum(num) {
for k, v in [{12:"T"},{9:"B"},{6:"M"},{3:"K"}] {
for i, j in v
if (num >= (10**i))
return % SubStr(num/(10**i),1,5) j
}
return num
}
1.234B
1.234M
1.234K
12
andreas#Nasa:~$ sudo -i
InputBox, num, Num Input, Input the number you want to be converted
if num is not Integer
return
MsgBox, % "Num is: " . num
MsgBox, % "this is converted: " . Converter.Convert(num)
return
class Converter {
static 1 := "k"
static 2 := "M"
static 3 := "G"
static 4 := "T"
Convert(int){
if int is not Integer
Throw, Exception("Illegal type", -1)
size := Floor(Floor(Log(int)) / 3)
if(size == 0)
return int
While(true){
Try {
ending := this[size]
break
}
Catch e {
if(e.Message == "key to great")
size--
}
}
return, Round(Floor(int / (10 ** (size * 3 - 1)))/ 10, 1) . Ending
}
__Get(vKey){
if(vKey > 0)
Throw, Exception("key to great")
return, 0
}
}
I am immensely grateful to each of them and to BoBo and elmodo7 for helping me this morning.

andreas#Nasa:~$ sudo -i
InputBox, num, Num Input, Input the number you want to be converted
if num is not Integer
return
MsgBox, % "Num is: " . num
MsgBox, % "this is converted: " . Converter.Convert(num)
return
class Converter {
static 1 := "k"
static 2 := "M"
static 3 := "B"
static 4 := "T"
Convert(int){
if int is not Integer
Throw, Exception("Illegal type", -1)
size := Floor(Floor(Log(int)) / 3)
if(size == 0)
return int
While(true){
Try {
ending := this[size]
break
}
Catch e {
if(e.Message == "key to great")
size--
}
}
return, Round(Floor(int / (10 ** (size * 3 - 1)))/ 10, 1) . Ending
}
__Get(vKey){
if(vKey > 0)
Throw, Exception("key to great")
return, 0
}
}
edit: personally all this is beyond me but this solution is his final answer.
conv := new Converter()
Loop, 10 {
Random, num, 0, 2147483647
num := num * 1000000
Print("Num is: " . num . " and this is converted: " . conv.Convert(num))
}
return
class Converter {
__New(){
this.endingChars := new EndChars("k", "M", "G", "T") ; put the endings for each step here in the correct order...
}
Convert(int){
if int is not Integer
Throw, Exception("Illegal type", -1)
size := Floor(Floor(Log(int)) / 3)
if(size == 0)
return int
While(size > 0){
Try {
ending := this.endingChars[size]
break
}
Catch e {
size--
}
}
return, Round(Floor(int / (10 ** (size * 3 - 1)))/ 10, 1) . ending
}
}
class EndChars {
__New(EndingChars*){
for k, i in EndingChars
this[k] := i
}
__Get(vKey){
if(vKey > 0)
Throw, Exception("key to great")
return, 0
}
}
and you can just add the next character in line to EndChars

Related

Auto Hot Key script to Copy data from a Doc file and Email it with an app or chrome Browser

I have some text in a .DOC File Which is stored on Desktop. Is this possible When
If I press CTRL+Q Then, Text inside that file gets copied
And email it via any app or Mail app that is included in window10 to the person that are shown in the picture. How I want to email
***> You can also help me out, as I have the url of the email, I just have
to reply there after opening the mail url and click send button.***
Once you've got the file content as text, you can then piece together a mailto: URI. By the RFC 6068 spec, a parser should accept the primary email, subject and body - the other fields (such as CC addresses) are up to the parser to implement.
Here's a quick script I threw together from snippets I've found.
#SingleInstance Force
EmailRecipient := "target#example.com"
EmailCC := ["target2#example.com", "target3#example.com"]
EmailSubject := "MY WORK PROGRESS"
^Q::
; Step 1) Gets filepath of first file
FirstFilePath := getFirstSelected()
; Step 2) Makes sure its a DOC or DOCX file
if (!(SubStr(FirstFilePath, -3) = ".doc" || SubStr(FirstFilePath, -4) = ".docx")) {
MsgBox 0x1010, Doc Mailer, % "Not a doc/docx file!"
return
}
; Learning one
; https://autohotkey.com/board/topic/73386-fileread-word-docx-com-l-line-40-error/?p=494436
; Step 3) Opens it as a COM Object and copies its text content to the clipboard
oDoc := ComObjGet(FirstFilePath)
oDoc.Range.FormattedText.Copy ; OR oDoc.Range.Text.Copy
oDoc.Close(0)
; Step 4) Takes the content on the clipboard and URI encodes it
encodedBody:=UriEncode(clipboard)
; Step 5) Build GET query string parts
params := []
if (EmailCC && EmailCC.Length()) {
params.Push("cc=" . UriEncode(StrJoin(EmailCC, ",")))
}
if (EmailSubject) {
params.Push("subject=" . UriEncode(EmailSubject))
}
if (encodedBody) {
params.Push("body=" . encodedBody)
}
paramsStr := StrJoin(params, "&")
; Step 6) Build the mailto: URI
;MsgBox % "mailto:" . EmailRecipient . (paramsStr ? "?" . paramsStr : "")
Run, % "mailto:" . EmailRecipient . (paramsStr ? "?" . paramsStr : "")
return
; ---------------------
; Modified from Masonjar13's function
; https://www.autohotkey.com/boards/viewtopic.php?p=154791#p154791
getFirstSelected(){
cO:=clipboardAll
clipboard:=
send ^c
clipWait
selected:=clipboard
clipboard:=cO
return StrSplit(selected, "`r`n")[1]
}
; ---------------------
; https://autohotkey.com/board/topic/75390-ahk-l-unicode-uri-encode-url-encode-function/?p=480216
; modified from jackieku's code (http://www.autohotkey.com/forum/post-310959.html#310959)
UriEncode(Uri, Enc = "UTF-8")
{
StrPutVar(Uri, Var, Enc)
f := A_FormatInteger
SetFormat, IntegerFast, H
Loop
{
Code := NumGet(Var, A_Index - 1, "UChar")
If (!Code)
Break
If (Code >= 0x30 && Code <= 0x39 ; 0-9
|| Code >= 0x41 && Code <= 0x5A ; A-Z
|| Code >= 0x61 && Code <= 0x7A) ; a-z
Res .= Chr(Code)
Else
Res .= "%" . SubStr(Code + 0x100, -1)
}
SetFormat, IntegerFast, %f%
Return, Res
}
UriDecode(Uri, Enc = "UTF-8")
{
Pos := 1
Loop
{
Pos := RegExMatch(Uri, "i)(?:%[\da-f]{2})+", Code, Pos++)
If (Pos = 0)
Break
VarSetCapacity(Var, StrLen(Code) // 3, 0)
StringTrimLeft, Code, Code, 1
Loop, Parse, Code, `%
NumPut("0x" . A_LoopField, Var, A_Index - 1, "UChar")
StringReplace, Uri, Uri, `%%Code%, % StrGet(&Var, Enc), All
}
Return, Uri
}
StrPutVar(Str, ByRef Var, Enc = "")
{
Len := StrPut(Str, Enc) * (Enc = "UTF-16" || Enc = "CP1200" ? 2 : 1)
VarSetCapacity(Var, Len, 0)
Return, StrPut(Str, &Var, Enc)
}
; ---------------------
StrJoin(arr, delim = ",") {
ret := ""
Loop % arr.Length()
ret := ret . (A_Index = 1 ? "" : delim) . arr[A_Index]
return ret
}

How to format a number into thousands, millions and billions with dart/flutter?

How to get a number converted into something like this: 12K, 1.5M, 4.2B from a normal number like: 134900.
This is a minimalist function, of course you'll have to add validation code to verify if the number is valid before executing the function. Otherwise Enjoy ...
void main() {
double num = 1250;
var myNumber = k_m_b_generator(num);
print(myNumber);
}
String k_m_b_generator(num) {
if (num > 999 && num < 99999) {
return "${(num / 1000).toStringAsFixed(1)} K";
} else if (num > 99999 && num < 999999) {
return "${(num / 1000).toStringAsFixed(0)} K";
} else if (num > 999999 && num < 999999999) {
return "${(num / 1000000).toStringAsFixed(1)} M";
} else if (num > 999999999) {
return "${(num / 1000000000).toStringAsFixed(1)} B";
} else {
return num.toString();
}
}
You can use flutter's NumberFormat class with the compact function.
formatNumber(dynamic myNumber) {
// Convert number into a string if it was not a string previously
String stringNumber = myNumber.toString();
// Convert number into double to be formatted.
// Default to zero if unable to do so
double doubleNumber = double.tryParse(stringNumber) ?? 0;
// Set number format to use
NumberFormat numberFormat = new NumberFormat.compact();
return numberFormat.format(doubleNumber);
}
The answer is not entirely correct. If you test it, you will see what i meant. Base on the answer above, I created this solution:
String numberFormat(int n) {
String num = n.toString();
int len = num.length;
if (n >= 1000 && n < 1000000) {
return num.substring(0, len - 3) + '.' + num.substring(len - 3, 1 + (len - 3)) + 'k';
} else if (n >= 1000000 && n < 1000000000) {
return num.substring(0, len - 6) + '.' + num.substring(len - 6, 1 + (len - 6)) + 'm';
} else if (n > 1000000000) {
return num.substring(0, len - 9) + '.' + num.substring(len - 9, 1 + (len - 9)) + 'b';
} else {
return num.toString();
}
}

Google Translate TTS API blocked

Google implemented a captcha to block people from accessing the TTS translate API https://translate.google.com/translate_tts?ie=UTF-8&q=test&tl=zh-TW. I was using it in my mobile application. Now, it is not returning anything. How do I get around the captcha?
Add the qualifier '&client=tw-ob' to the end of your query.
https://translate.google.com/translate_tts?ie=UTF-8&q=test&tl=zh-TW&client=tw-ob
This answer no longer works consistently. Your ip address will be blocked by google temporarily if you abuse this too much.
there are 3 main issues:
you must include "client" in your query string (client=t seems to work).
(in case you are trying to retrieve it using AJAX) the Referer of the HTTP request must be https://translate.google.com/
"tk" field changes for every query, and it must be populated with a matching hash:
tk = hash(q, TKK), where q is the text to be TTSed, and TKK is a var in the global scope when you load translate.google.com: (type 'window.TKK' in the console). see the hash function at the bottom of this reply (calcHash).
to summarize:
function generateGoogleTTSLink(q, tl, tkk) {
var tk = calcHash(q, tkk);
return `https://translate.google.com/translate_tts?ie=UTF-8&total=1&idx=0&client=t&ttsspeed=1&tl=${tl}&tk=${tk}&q=${q}&textlen=${q.length}`;
}
generateGoogleTTSLink('ciao', 'it', '410353.1336369826');
// see definition of "calcHash" in the bottom of this comment.
=> to get your hands on a TKK, you can open Google Translate website, then type "TKK" in developer tools' console (e.g.: "410353.1336369826").
NOTE that TKK value changes every hour, and so, old TKKs might get blocked at some point, and refreshing it may be necessary (although so far it seems like old keys can work for a LONG time).
if you DO wish to periodically refresh TKK, it can be automated pretty easily, but not if you're running your code from the browser.
you can find a full NodeJS implementation here:
https://github.com/guyrotem/google-translate-server.
it exposes a minimal TTS API (query, language), and is deployed to a free Heroku server, so you can test it online if you like.
function shiftLeftOrRightThenSumOrXor(num, opArray) {
return opArray.reduce((acc, opString) => {
var op1 = opString[1]; // '+' | '-' ~ SUM | XOR
var op2 = opString[0]; // '+' | '^' ~ SLL | SRL
var xd = opString[2]; // [0-9a-f]
var shiftAmount = hexCharAsNumber(xd);
var mask = (op1 == '+') ? acc >>> shiftAmount : acc << shiftAmount;
return (op2 == '+') ? (acc + mask & 0xffffffff) : (acc ^ mask);
}, num);
}
function hexCharAsNumber(xd) {
return (xd >= 'a') ? xd.charCodeAt(0) - 87 : Number(xd);
}
function transformQuery(query) {
for (var e = [], f = 0, g = 0; g < query.length; g++) {
var l = query.charCodeAt(g);
if (l < 128) {
e[f++] = l; // 0{l[6-0]}
} else if (l < 2048) {
e[f++] = l >> 6 | 0xC0; // 110{l[10-6]}
e[f++] = l & 0x3F | 0x80; // 10{l[5-0]}
} else if (0xD800 == (l & 0xFC00) && g + 1 < query.length && 0xDC00 == (query.charCodeAt(g + 1) & 0xFC00)) {
// that's pretty rare... (avoid ovf?)
l = (1 << 16) + ((l & 0x03FF) << 10) + (query.charCodeAt(++g) & 0x03FF);
e[f++] = l >> 18 | 0xF0; // 111100{l[9-8*]}
e[f++] = l >> 12 & 0x3F | 0x80; // 10{l[7*-2]}
e[f++] = l & 0x3F | 0x80; // 10{(l+1)[5-0]}
} else {
e[f++] = l >> 12 | 0xE0; // 1110{l[15-12]}
e[f++] = l >> 6 & 0x3F | 0x80; // 10{l[11-6]}
e[f++] = l & 0x3F | 0x80; // 10{l[5-0]}
}
}
return e;
}
function normalizeHash(encondindRound2) {
if (encondindRound2 < 0) {
encondindRound2 = (encondindRound2 & 0x7fffffff) + 0x80000000;
}
return encondindRound2 % 1E6;
}
function calcHash(query, windowTkk) {
// STEP 1: spread the the query char codes on a byte-array, 1-3 bytes per char
var bytesArray = transformQuery(query);
// STEP 2: starting with TKK index, add the array from last step one-by-one, and do 2 rounds of shift+add/xor
var d = windowTkk.split('.');
var tkkIndex = Number(d[0]) || 0;
var tkkKey = Number(d[1]) || 0;
var encondingRound1 = bytesArray.reduce((acc, current) => {
acc += current;
return shiftLeftOrRightThenSumOrXor(acc, ['+-a', '^+6'])
}, tkkIndex);
// STEP 3: apply 3 rounds of shift+add/xor and XOR with they TKK key
var encondingRound2 = shiftLeftOrRightThenSumOrXor(encondingRound1, ['+-3', '^+b', '+-f']) ^ tkkKey;
// STEP 4: Normalize to 2s complement & format
var normalizedResult = normalizeHash(encondingRound2);
return normalizedResult.toString() + "." + (normalizedResult ^ tkkIndex)
}
// usage example:
var tk = calcHash('hola', '409837.2120040981');
console.log('tk=' + tk);
// OUTPUT: 'tk=70528.480109'
You can also try this format :
pass q= urlencode format of your language
(In JavaScript you can use the encodeURI() function & PHP has the rawurlencode() function)
pass tl = language short name (suppose bangla = bn)
Now try this :
https://translate.google.com.vn/translate_tts?ie=UTF-8&q=%E0%A6%A2%E0%A6%BE%E0%A6%95%E0%A6%BE+&tl=bn&client=tw-ob
First, to avoid captcha, you have to set a proper user-agent like: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0"
Then to not being blocked you must provide a proper token ("tk" get parameter) for each single request.
On the web you can find many different kind of scripts that try to calculate the token after a lot of reverse engineering...but every time the big G change the algorithm you're stuck again, so it's much easier to retrieve your token just observing in deep similar requests to translate page (with your text in the url).
You can read the token time by time grepping "tk=" from the output of this simple code with phantomjs:
"use strict";
var page = require('webpage').create();
var system = require('system');
var args = system.args;
if (args.length != 2) { console.log("usage: "+args[0]+" text"); phantom.exit(1); }
page.onConsoleMessage = function(msg) { console.log(msg); };
page.onResourceRequested = function(request) { console.log('Request ' + JSON.stringify(request, undefined, 4)); };
page.open("https://translate.google.it/?hl=it&tab=wT#fr/it/"+args[1], function(status) {
if (status === "success") { phantom.exit(0); }
else { phantom.exit(1); }
});
so in the end you can get your speech with something like:
wget -U "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0"
"http://translate.google.com/translate_tts?ie=UTF-8&tl=it&tk=52269.458629&q=ciao&client=t" -O ciao.mp3
(token are probably time based so this link may not work tomorrow)
I rewrote Guy Rotem's answer in Java, so if you prefer Java over Javascript, feel free to use:
public class Hasher {
public long shiftLeftOrRightThenSumOrXor(long num, String[] opArray) {
long result = num;
int current = 0;
while (current < opArray.length) {
char op1 = opArray[current].charAt(1); // '+' | '-' ~ SUM | XOR
char op2 = opArray[current].charAt(0); // '+' | '^' ~ SLL | SRL
char xd = opArray[current].charAt(2); // [0-9a-f]
assertError(op1 == '+'
|| op1 == '-', "Invalid OP: " + op1);
assertError(op2 == '+'
|| op2 == '^', "Invalid OP: " + op2);
assertError(('0' <= xd && xd <= '9')
|| ('a' <= xd && xd <='f'), "Not an 0x? value: " + xd);
int shiftAmount = hexCharAsNumber(xd);
int mask = (op1 == '+') ? ((int) result) >>> shiftAmount : ((int) result) << shiftAmount;
long subresult = (op2 == '+') ? (((int) result) + ((int) mask) & 0xffffffff)
: (((int) result) ^ mask);
result = subresult;
current++;
}
return result;
}
public void assertError(boolean cond, String e) {
if (!cond) {
System.err.println();
}
}
public int hexCharAsNumber(char xd) {
return (xd >= 'a') ? xd - 87 : Character.getNumericValue(xd);
}
public int[] transformQuery(String query) {
int[] e = new int[1000];
int resultSize = 1000;
for (int f = 0, g = 0; g < query.length(); g++) {
int l = query.charAt(g);
if (l < 128) {
e[f++] = l; // 0{l[6-0]}
} else if (l < 2048) {
e[f++] = l >> 6 | 0xC0; // 110{l[10-6]}
e[f++] = l & 0x3F | 0x80; // 10{l[5-0]}
} else if (0xD800 == (l & 0xFC00) &&
g + 1 < query.length() && 0xDC00 == (query.charAt(g + 1) & 0xFC00)) {
// that's pretty rare... (avoid ovf?)
l = (1 << 16) + ((l & 0x03FF) << 10) + (query.charAt(++g) & 0x03FF);
e[f++] = l >> 18 | 0xF0; // 111100{l[9-8*]}
e[f++] = l >> 12 & 0x3F | 0x80; // 10{l[7*-2]}
e[f++] = l & 0x3F | 0x80; // 10{(l+1)[5-0]}
} else {
e[f++] = l >> 12 | 0xE0; // 1110{l[15-12]}
e[f++] = l >> 6 & 0x3F | 0x80; // 10{l[11-6]}
e[f++] = l & 0x3F | 0x80; // 10{l[5-0]}
}
resultSize = f;
}
return Arrays.copyOf(e, resultSize);
}
public long normalizeHash(long encondindRound2) {
if (encondindRound2 < 0) {
encondindRound2 = (encondindRound2 & 0x7fffffff) + 0x80000000L;
}
return (encondindRound2) % 1_000_000;
}
/*
/ EXAMPLE:
/
/ INPUT: query: 'hola', windowTkk: '409837.2120040981'
/ OUTPUT: '70528.480109'
/
*/
public String calcHash(String query, String windowTkk) {
// STEP 1: spread the the query char codes on a byte-array, 1-3 bytes per char
int[] bytesArray = transformQuery(query);
// STEP 2: starting with TKK index,
// add the array from last step one-by-one, and do 2 rounds of shift+add/xor
String[] d = windowTkk.split("\\.");
int tkkIndex = 0;
try {
tkkIndex = Integer.valueOf(d[0]);
}
catch (Exception e) {
e.printStackTrace();
}
long tkkKey = 0;
try {
tkkKey = Long.valueOf(d[1]);
}
catch (Exception e) {
e.printStackTrace();
}
int current = 0;
long result = tkkIndex;
while (current < bytesArray.length) {
result += bytesArray[current];
long subresult = shiftLeftOrRightThenSumOrXor(result,
new String[] {"+-a", "^+6"});
result = subresult;
current++;
}
long encondingRound1 = result;
//System.out.println("encodingRound1: " + encondingRound1);
// STEP 3: apply 3 rounds of shift+add/xor and XOR with they TKK key
long encondingRound2 = ((int) shiftLeftOrRightThenSumOrXor(encondingRound1,
new String[] {"+-3", "^+b", "+-f"})) ^ ((int) tkkKey);
//System.out.println("encodingRound2: " + encondingRound2);
// STEP 4: Normalize to 2s complement & format
long normalizedResult = normalizeHash(encondingRound2);
//System.out.println("normalizedResult: " + normalizedResult);
return String.valueOf(normalizedResult) + "."
+ (((int) normalizedResult) ^ (tkkIndex));
}
}

Use AHK PostMessage / SendMessage or DllCall( "SendMessage" to get the contents of a listview control

I am trying to get the contents of a listview control in another application using AHK. I tried using
ControlGet, List, List,, ListViewWndClass1, WindowTitle
in AutoHotKey but this did not work. Is there a way to get listview control contents using AHK PostMessage / SendMessage or DllCall( "SendMessage"?
Try this:
GetListViewItemText(item_index, sub_index, ctrl_id, win_id)
{
;const
MAX_TEXT = 260
VarSetCapacity(szText, MAX_TEXT, 0)
VarSetCapacity(szClass, MAX_TEXT, 0)
ControlGet, hListView, Hwnd, , %ctrl_id%, ahk_id %win_id%
DllCall("GetClassName", UInt,hListView, Str,szClass, Int,MAX_TEXT)
if (DllCall("lstrcmpi", Str,szClass, Str,"SysListView32") == 0 || DllCall("lstrcmpi", Str,szClass, Str,"TListView") == 0)
{
GetListViewText(hListView, item_index, sub_index, szText, MAX_TEXT)
}
return %szText%
}
GetListViewText(hListView, iItem, iSubItem, ByRef lpString, nMaxCount)
{
;const
NULL = 0
PROCESS_ALL_ACCESS = 0x001F0FFF
INVALID_HANDLE_VALUE = 0xFFFFFFFF
PAGE_READWRITE = 4
FILE_MAP_WRITE = 2
MEM_COMMIT = 0x1000
MEM_RELEASE = 0x8000
LV_ITEM_mask = 0
LV_ITEM_iItem = 4
LV_ITEM_iSubItem = 8
LV_ITEM_state = 12
LV_ITEM_stateMask = 16
LV_ITEM_pszText = 20
LV_ITEM_cchTextMax = 24
LVIF_TEXT = 1
LVM_GETITEM = 0x1005
SIZEOF_LV_ITEM = 0x28
SIZEOF_TEXT_BUF = 0x104
SIZEOF_BUF = 0x120
SIZEOF_INT = 4
SIZEOF_POINTER = 4
;var
result := 0
hProcess := NULL
dwProcessId := 0
if lpString <> NULL && nMaxCount > 0
{
DllCall("lstrcpy", Str,lpString, Str,"")
DllCall("GetWindowThreadProcessId", UInt,hListView, UIntP,dwProcessId)
hProcess := DllCall("OpenProcess", UInt,PROCESS_ALL_ACCESS, Int,false, UInt,dwProcessId)
if hProcess <> NULL
{
;var
lpProcessBuf := NULL
hMap := NULL
hKernel := DllCall("GetModuleHandle", Str,"kernel32.dll", UInt)
pVirtualAllocEx := DllCall("GetProcAddress", UInt,hKernel, Str,"VirtualAllocEx", UInt)
if pVirtualAllocEx == NULL
{
hMap := DllCall("CreateFileMapping", UInt,INVALID_HANDLE_VALUE, Int,NULL, UInt,PAGE_READWRITE, UInt,0, UInt,SIZEOF_BUF, UInt)
if hMap <> NULL
lpProcessBuf := DllCall("MapViewOfFile", UInt,hMap, UInt,FILE_MAP_WRITE, UInt,0, UInt,0, UInt,0, UInt)
}
else
{
lpProcessBuf := DllCall("VirtualAllocEx", UInt,hProcess, UInt,NULL, UInt,SIZEOF_BUF, UInt,MEM_COMMIT, UInt,PAGE_READWRITE)
}
if lpProcessBuf <> NULL
{
;var
VarSetCapacity(buf, SIZEOF_BUF, 0)
InsertIntegerSL(LVIF_TEXT, buf, LV_ITEM_mask, SIZEOF_INT)
InsertIntegerSL(iItem, buf, LV_ITEM_iItem, SIZEOF_INT)
InsertIntegerSL(iSubItem, buf, LV_ITEM_iSubItem, SIZEOF_INT)
InsertIntegerSL(lpProcessBuf + SIZEOF_LV_ITEM, buf, LV_ITEM_pszText, SIZEOF_POINTER)
InsertIntegerSL(SIZEOF_TEXT_BUF, buf, LV_ITEM_cchTextMax, SIZEOF_INT)
if DllCall("WriteProcessMemory", UInt,hProcess, UInt,lpProcessBuf, UInt,&buf, UInt,SIZEOF_BUF, UInt,NULL) <> 0
if DllCall("SendMessage", UInt,hListView, UInt,LVM_GETITEM, Int,0, Int,lpProcessBuf) <> 0
if DllCall("ReadProcessMemory", UInt,hProcess, UInt,lpProcessBuf, UInt,&buf, UInt,SIZEOF_BUF, UInt,NULL) <> 0
{
DllCall("lstrcpyn", Str,lpString, UInt,&buf + SIZEOF_LV_ITEM, Int,nMaxCount)
result := DllCall("lstrlen", Str,lpString)
}
}
if lpProcessBuf <> NULL
if pVirtualAllocEx <> NULL
DllCall("VirtualFreeEx", UInt,hProcess, UInt,lpProcessBuf, UInt,0, UInt,MEM_RELEASE)
else
DllCall("UnmapViewOfFile", UInt,lpProcessBuf)
if hMap <> NULL
DllCall("CloseHandle", UInt,hMap)
DllCall("CloseHandle", UInt,hProcess)
}
}
return result
}
; *********************************
; Required functions - ExtractInteger, InsertInteger
; - original versions from Version 1.0.44.06 of the AutoHotkey help file
; by Chris Mallett
; // Renamed in case someone is using a modified version of these functions
; // somewhere else in their code
; *********************************
ExtractIntegerSL(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
; pSource is a string (buffer) whose memory area contains a raw/binary integer at pOffset.
; The caller should pass true for pSigned to interpret the result as signed vs. unsigned.
; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int).
; pSource must be ByRef to avoid corruption during the formal-to-actual copying process
; (since pSource might contain valid data beyond its first binary zero).
{
Loop %pSize% ; Build the integer by adding up its bytes.
result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1)
if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
return result ; Signed vs. unsigned doesn't matter in these cases.
; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
return -(0xFFFFFFFF - result + 1)
}
; *********************************
InsertIntegerSL(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; The caller must ensure that pDest has sufficient capacity. To preserve any existing contents in pDest,
; only pSize number of bytes starting at pOffset are altered in it.
{
Loop %pSize% ; Copy each byte in the integer into the structure as raw binary data.
DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
}
; *********************************
Should work somewhat like this:
WinGet, hWnd, ID, My WinTitle
GetListViewItemText(1, 1, "ListViewWndClass1", hWnd)
source: http://www.autohotkey.com/board/topic/18299-reading-listview-of-another-app/

finding the left substring is equal to right substring

Write a function which given a string S returns the index (counting from 0) of character such that the substring on its left is a reversed susbstring on its right (or -1 if such an index does not exist).
For example, given a string
racecar
Function should return 3, because the substring on the left of the character e at index 3 is rac, and the one on the right is car.
get the length/2 and verify lengths first and then if the lengths are same then reverse the first half and compare with the second.
Example function:
private int TestMethod1(string str)
{
if (str.Length > 0)
{
if (str.Length % 2 != 0)
{
string strFront = string.Empty;
for (int i = (str.Length / 2) - 1; i >= 0; i--)
{
strFront += str.Substring(i, 1);
}
if (strFront.Equals(str.Substring((str.Length / 2) + 1)))
{
return str.Length / 2;
}
}
}
return -1;
}