FHannes Posted August 21, 2012 Share Posted August 21, 2012 https://github.com/OSI1/OSI1/blob/master/Divi/Array.scar#L216 Quote Link to comment Share on other sites More sharing options...
MarkD Posted August 22, 2012 Author Share Posted August 22, 2012 Well, that worked pretty good :-) [scar]program FindTextBox; var TxtBox,x,y,t,length: Integer; List: TPointArray; Bmp: TSCARBitmap; Cl: TSCARClient; Procedure InitDTM; Begin TxtBox := DTMFromString('78DA6334666260D807C448606F3E2F986684F' + '219CD81F21750D5945AB1A1AA0903CAEF4755F3EB58148A1A007F' + '110728'); End; Procedure InitBMP; Begin Bmp := TSCARBitmap.Create(''); Bmp := GetClient.Capture; Cl := SetClient(TSCARBitmapClient.Create(Bmp)); end; begin ClearDebug; InitDTM; //Load DTM InitBMP; //Load BMP SetLength(List, 40); //reserve some playground List[0] := Point(0,0); //make sure there is at least something //to prevent issues when searching for t := 0 to 19 do begin if(FindDTM(TxtBox,x,y,0,0,1680,1050)) then begin WriteLn(x); WriteLn(y); //MoveMouse(x,y); //point to match //ClickMouse(x,y,False); Wait(200); //for debug Bmp.Pixels[x,y] := clRed; //paint it List[t] := Point(x,y); //add to list //ClickMouse(715,949,False); end; end; SetClient(Cl).Free; Bmp.Free; length := SizeOf(List); for t := 0 to length do begin // WriteLn(List[t]); end; end.[/scar] I have been looking for a TPointToStr function, but it isn't really necessary. I'll probably erase that bit in the future. Mouse actions don't work on canvas, so I guess I'll have to find the DTMs first, set the client back to my browser and start clicking there. Shouldn't be to much of a problem. The problems with OCR still persist, so I'll try to put things together first (implement DTM in main program and do a little clean up) and give OCR another try. Perhaps OCR gives less trouble when reading from canvas then directly from screen, we'll see. Quote Link to comment Share on other sites More sharing options...
Janilabo Posted August 22, 2012 Share Posted August 22, 2012 Well, that worked pretty good :-) [scar]program FindTextBox; var TxtBox,x,y,t,length: Integer; List: TPointArray; Bmp: TSCARBitmap; Cl: TSCARClient; Procedure InitDTM; Begin TxtBox := DTMFromString('78DA6334666260D807C448606F3E2F986684F' + '219CD81F21750D5945AB1A1AA0903CAEF4755F3EB58148A1A007F' + '110728'); End; Procedure InitBMP; Begin Bmp := TSCARBitmap.Create(''); Bmp := GetClient.Capture; Cl := SetClient(TSCARBitmapClient.Create(Bmp)); end; begin ClearDebug; InitDTM; //Load DTM InitBMP; //Load BMP SetLength(List, 40); //reserve some playground List[0] := Point(0,0); //make sure there is at least something //to prevent issues when searching for t := 0 to 19 do begin if(FindDTM(TxtBox,x,y,0,0,1680,1050)) then begin WriteLn(x); WriteLn(y); //MoveMouse(x,y); //point to match //ClickMouse(x,y,False); Wait(200); //for debug Bmp.Pixels[x,y] := clRed; //paint it List[t] := Point(x,y); //add to list //ClickMouse(715,949,False); end; end; SetClient(Cl).Free; Bmp.Free; length := SizeOf(List); for t := 0 to length do begin // WriteLn(List[t]); end; end.[/scar] I have been looking for a TPointToStr function, but it isn't really necessary. That's really simple to do, here: [scar]function PointToStr(pt: TPoint): string; begin Result := (IntToStr(pt.X) + ',' + IntToStr(pt.Y)); end; function CoordsToStr(X, Y: Integer): string; begin Result := (IntToStr(X) + ',' + IntToStr(Y)); end; begin WriteLn(PointToStr(Point(Random(101), Random(101)))); WriteLn(CoordsToStr(Random(101), Random(101))); end.[/scar] -Jani Quote Link to comment Share on other sites More sharing options...
MarkD Posted August 23, 2012 Author Share Posted August 23, 2012 So, the current version of the project: [scar]//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*// // Title: TBRPG gatherer (Ikariam version) // // Purpose: Gathering information from TBRPGs // // Status: Work In Progress // // Author: MarkD aka MatVis // // // // To do: // // - after DTM, switch back to client, click// // coords, read data and return to BMP // // - OCR // // // // Thanks to all who've helped! // //*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*// program TBRPGgIV; var x_a,y_a : array [0..5] of Integer; xi,yi,watercheck,water,TxtBox,x,y,t,a_i,length : Integer; List: TPointArray; Bmp: TSCARBitmap; Cl: TSCARClient; //list of procedures procedure MoveNClick(mx,my : integer); begin Wait(632); MoveMouse(mx,my); Wait(221); MouseBtnDown(mx,my, False); Wait(198); MouseBtnUp(mx + 38, my + 2, False); end; Procedure InitDTM; Begin TxtBox := DTMFromString('78DA6334666260D807C448606F3E2F986684F' + '219CD81F21750D5945AB1A1AA0903CAEF4755F3EB58148A1A007F' + '110728'); End; procedure InitXYArrays; begin for a_i := 0 to 5 do begin x_a[a_i] := a_i+1; y_a[a_i] := a_i+1; end; end; Procedure InitBMP; Begin Bmp := TSCARBitmap.Create(''); Bmp := GetClient.Capture; Cl := SetClient(TSCARBitmapClient.Create(Bmp)); end; Procedure FreeBMP; Begin SetClient(Cl).Free; Bmp.Free; end; function PointToStr(pt: TPoint): string; begin Result := (IntToStr(pt.X) + ',' + IntToStr(pt.Y)); end; //main program begin ClearDebug; InitDTM; InitXYArrays; SetLength(List, 30); //reserve some playground List[0] := Point(0,0); //make sure there is at least something //to prevent issues when searching water := 12418074; //define water //var 12288039 11564307 12222763 for xi := 0 to 1 do begin Wait(697); for yi := 0 to 2 do begin MoveNClick(594,949); TypeText(IntToStr(x_a[xi])); //give new coords for left box MoveNClick(658,949); TypeText(IntToStr(y_a[yi])); //give new coords for right box Wait(818); MoveMouse(715,949); Wait(557); ClickMouse(715,949,False); //click go Wait(567); watercheck := GetColor(945,600); WriteLn(IntToStr(watercheck)); if ((watercheck = water)) then //if there is water instead of an island, Continue; //skip to next coordinate Wait(121); MoveMouse(945,600); //move mouse to island Wait(420); ClickMouse(945,600,False); //click island //switching to island view InitBMP; for t := 0 to 19 do begin if(FindDTM(TxtBox,x,y,0,0,1680,1050)) then begin WriteLn(x); WriteLn(y); Bmp.Pixels[x,y] := clRed; //paint it List[t] := Point(x,y); //add to list end; end; FreeBMP; //destruct length := (SizeOf(List) - 1); for t := 0 to length do begin WriteLn(PointToStr(List[t])); end; WriteLn(IntToStr(length)); Wait(884); MoveMouse(80,220); ClickMouse(80,225,False); //return to world screen //switching to world view end; end; WriteLn('Done'); end. [/scar] Perhaps OCR isn't even necessary. All characters are selectable, so if there is any way to make SCAR use ctrl+c and store this into a string, it's fine as well. If the storing part is a problem but ctrl+c works, I could copy the text to an instance of notepad and read from there. If ctrl+c doesn't work, I could even try it with the Right mouse button. Quote Link to comment Share on other sites More sharing options...
Janilabo Posted August 23, 2012 Share Posted August 23, 2012 Nice work, MarkD! Btw, replace: [scar]Procedure InitBMP; Begin Bmp := TSCARBitmap.Create(''); Bmp := GetClient.Capture; Cl := SetClient(TSCARBitmapClient.Create(Bmp)); end;[/scar] ..with this: [scar]Procedure InitBMP; Begin Bmp := GetClient.Capture; Cl := SetClient(TSCARBitmapClient.Create(Bmp)); end;[/scar] Sorry, it was my bad I used that TSCARBitmap.Create('') there, even though its not needed at all (and actually SHOULDN'T be used, because GetClient.Capture builds the TSCARBitmap) Also, remember to add that FreeDTM to the end of the script, as it is a good habbit to free everything that you have loaded with SCAR. Quote Link to comment Share on other sites More sharing options...
MarkD Posted August 26, 2012 Author Share Posted August 26, 2012 The text that you have entered is too long (481238 characters). Please shorten it to 25000 characters long. So the result is missing. Couldn't figure out why Bmp should be filled twice, now I know why. It shouldn't :-) I've been trying to get some reading done. So I started Notepad (not the ++ version, redefining fonts is a pain in the * there) and typed ' More text! ' in Verdana 12. [scar]begin ClearDebug; c := LoadCharsFromFont2('Verdana', 12, False, False, False, False); s := 'More text!' for x := 1 to 400 do begin for y := 1 to 400 do begin WriteLn(IsTextAtEx(x,y,s,50,c,false,false,0,0,0)); end; end; end.[/scar] I really DON'T recommend you to try this at home. Why? Successfully executed (2798028,5084 ms) Output (removed). Summary: 0's till ln 110110, 1's till 110145, 0's till 110451, 1's till 132673, 0's till 132898, 1's till 132936, 0's till 133007, a lone zero at 133008 (?), 1's till 133030, 0's till 113111, more like that. Next question: Is there any usefulness in these numbers? The text was on the first line of notepad, why does it take 275 to the right to find something? Is this because of the tolerance? Are there quicker ways to detect text? And yes, I know it would've been clearer to switch x and y in the increment process (it's in a way reading top to bottom now). Quote Link to comment Share on other sites More sharing options...
LordJashin Posted August 27, 2012 Share Posted August 27, 2012 We can do so much with the screen reading, but I want a dang keyboard driver or something because a ton of games and programs don't allow SCAR's keyboard input function to work . Quote Link to comment Share on other sites More sharing options...
MarkD Posted September 8, 2012 Author Share Posted September 8, 2012 So, I'm pretty much stuck here. If I type a simple text in Notepad and use IsTextAt at the upper left coordinate of the first letter, it just says no. Whatever the tolerance is I give, whatever the color is, it just says no. GetTextAt only gives rubbish. I've tried both with SetFontSmoothing(false) in the script, the darn thing just doesn't give me any clues where to look for the problem. Is there anyone with experience in SCAR OCR that DID produce a working script? I haven't seen any of them so far. Eventually, I could hack my way around OCR (just click and copy about anything that looks like something valuable, paste it and sort it out later). But I won't. At least not until I've run out of options, but the OCR thingy should be working. So why isn't it? Quote Link to comment Share on other sites More sharing options...
FHannes Posted September 8, 2012 Share Posted September 8, 2012 you have to disable font smoothing before you start notepad or it won't always update. It's best to just disable font smoothing globally before working with SCAR. On a side-note, you can get the content of the notepad window without OCR with 3.35 Quote Link to comment Share on other sites More sharing options...
LordJashin Posted September 9, 2012 Share Posted September 9, 2012 (edited) you have to disable font smoothing before you start notepad or it won't always update. It's best to just disable font smoothing globally before working with SCAR. On a side-note, you can get the content of the notepad window without OCR with 3.35 Yeah that window api again! ... Remember that FindTextTPA, or w/e. You can use TPA's and other things for text too. You can create a bitmap FROM a font! So if say, we wanted to write our own GetTextAt. I would go about it like this: Get the font's one letter bitmap into memory. Then at (x, y) search from there and all the way to the right as well. So it would be like...while not findbitmap(W); x := x + Width(W). This function would get a lot more complex with all its options though...for like the font's bitmap width and height. At X, Y search in a box with x until the end of the screen or you can set. Then Y would be the font bitmaps height. Then it could try to find the bitmap in the full box or w/e....if you get my idea We could make like a box function for it. FindBitmapBox for x, y for width and height of bitmap, etc, etc. Edited September 9, 2012 by LordJashin Quote Link to comment Share on other sites More sharing options...
MarkD Posted September 9, 2012 Author Share Posted September 9, 2012 The font smoothing was updated. My entire computer had font smoothing disabled the moment I ran the script (hard not to notice). Perhaps Janilabo has some good idea's, he's the one who wrote GetTextAt. I don't remember a FindTextTPA and I can't find anything like it on the TPA wiki. Yes, we can create bitmaps from fonts (pretty obvious, a font is actually a collection of bitmaps in some way). I'm not entirely sure what you're trying to do though. Are you suggesting to locate the coordinate of the first letter and read it by trial and error (compare it to every character in the alfabet available)? Quote Link to comment Share on other sites More sharing options...
Janilabo Posted September 9, 2012 Share Posted September 9, 2012 Well, not sure if these will help with your problem here, but anyways, I rewrote today my GetTextAt & IsTextAt. They are now based on GetTextAtEx2, which is a fixed version of GetTextAtEx (with fix for that good ol' width problem of the OCR) Here: function GetTextAtEx2(x, y, Tolerance, Chars: Integer; CheckShadow, CheckOutline: Boolean; MinSpacing, MaxSpacing, TextColor, TextLength: Integer; Strict: Boolean; Range: TCharRange): string; var e, l, t: Integer; b: TSCARBitmap; s: string; begin if (TextLength < 1) then Exit; t := TextLength; if (t > 9) then t := 10; while (l < TextLength) do begin s := GetTextAtEx((x + e), y, Tolerance, Chars, CheckShadow, CheckOutline, MinSpacing, MaxSpacing, TextColor, t, Strict, Range); Result := (Result + s); l := (l + Length(s)); if ((l + t) > TextLength) then t := (TextLength - l); b := CreateBitmapFromText(s, Chars, TextColor); e := (e + b.Width); b.Free; end; end; function GetTextAt(x, y, Tolerance, Chars, MinSpacing, MaxSpacing, TextColor, TextLength: Integer; Strict: Boolean; Range: TCharRange): string; begin Result := GetTextAtEx2(x, y, Tolerance, Chars, False, False, MinSpacing, MaxSpacing, TextColor, TextLength, Strict, Range); end; function IsTextAt(x, y: Integer; S: string; Tolerance, Chars, MinSpacing, MaxSpacing, TextColor: Integer): Boolean; begin Result := (S = GetTextAtEx2(x, y, Tolerance, Chars, False, False, MinSpacing, MaxSpacing, TextColor, Length(S), True, tr_AllChars)); end; NOTE: I added MinSpacing / MaxSpacing to both of em (GetTextAt / IsTextAt) Quote Link to comment Share on other sites More sharing options...
LordJashin Posted September 9, 2012 Share Posted September 9, 2012 The font smoothing was updated. My entire computer had font smoothing disabled the moment I ran the script (hard not to notice). Perhaps Janilabo has some good idea's, he's the one who wrote GetTextAt. I don't remember a FindTextTPA and I can't find anything like it on the TPA wiki. Yes, we can create bitmaps from fonts (pretty obvious, a font is actually a collection of bitmaps in some way). I'm not entirely sure what you're trying to do though. Are you suggesting to locate the coordinate of the first letter and read it by trial and error (compare it to every character in the alfabet available)? I'm not sure either. But I think fonts are collections of glyphs*, and idk how that works I forget. Janilabo's is good! I remember lols! GetTextAt, uses X, Y position. For the X pos, to the end of the screen on the X-axis or width provided GetTextAt will try to get the text. Now does GetTextAt use the Y efficient enough? For the Y, I think you should do it like this. For the highest height of the bitmaps for the font put in to GetTextAT, use that as a variable. Lets say the highest height is 60. Idk how GetTextAt works exactly. But I imagine that it just moves X over and searchs for the bitmap again. There is no changes in Y? So i think there should be. Because when I use GetTextAt, or EX or W/E I want it to do a BOX. Not just at that particular Y value. What if the text is one pixel higher? Scenario: All the text you are trying to get is at Y: 300. But you search at 299. So nothing shows up. BUT if you said like: from 300-400. BOOM box, and we get the text magically somehow... Something like that... tldr; Bring in xs, ys, xe, ye for the searching!!! Or just for the Y axis Quote Link to comment Share on other sites More sharing options...
Janilabo Posted September 9, 2012 Share Posted September 9, 2012 I'm not sure either. But I think fonts are collections of glyphs*, and idk how that works I forget. Janilabo's is good! I remember lols! GetTextAt, uses X, Y position. For the X pos, to the end of the screen on the X-axis or width provided GetTextAt will try to get the text. Now does GetTextAt use the Y efficient enough? For the Y, I think you should do it like this. For the highest height of the bitmaps for the font put in to GetTextAT, use that as a variable. Lets say the highest height is 60. Idk how GetTextAt works exactly. But I imagine that it just moves X over and searchs for the bitmap again. There is no changes in Y? So i think there should be. Because when I use GetTextAt, or EX or W/E I want it to do a BOX. Not just at that particular Y value. What if the text is one pixel higher? Scenario: All the text you are trying to get is at Y: 300. But you search at 299. So nothing shows up. BUT if you said like: from 300-400. BOOM box, and we get the text magically somehow... Something like that... tldr; Bring in xs, ys, xe, ye for the searching!!! Or just for the Y axis Mate, the function you are thinking/dreaming about would be GetTextIn.. GetTextAt[Ex] means getting the text from exact coordinate.. And yes, GetTextAt uses extra X in it, but that's for dealing with the problem of current OCR's width problems, which is limited to RuneScape bounds (I think). Freddy will change that in the future with new OCR (the current OCR is still the same old from ancient SCAR versions, IIRC) I'll see what I can come up with GetTextIn.. But I think it is a function that should be built-in to SCAR instead (future OCR), because it really requires as fast speed as possible. Quote Link to comment Share on other sites More sharing options...
LordJashin Posted September 9, 2012 Share Posted September 9, 2012 Mate, the function you are thinking/dreaming about would be GetTextIn.. GetTextAt[Ex] means getting the text from exact coordinate.. And yes, GetTextAt uses extra X in it, but that's for dealing with the problem of current OCR's width problems, which is limited to RuneScape bounds (I think). Freddy will change that in the future with new OCR (the current OCR is still the same old from ancient SCAR versions, IIRC) I'll see what I can come up with GetTextIn.. But I think it is a function that should be built-in to SCAR instead (future OCR), because it really requires as fast speed as possible. Yeah! I think GetTextIn might solve problems that people have with GetTextAt(ex)! Thanks for creating these Janilabo! Quote Link to comment Share on other sites More sharing options...
Janilabo Posted September 10, 2012 Share Posted September 10, 2012 (edited) Yeah! I think GetTextIn might solve problems that people have with GetTextAt(ex)! Thanks for creating these Janilabo!Hey mate, I have been thinking about ways to build the function.. But it's not the easiest thing to create, AT ALL... This is what I have came up with so far (uses currently SCAR's bugged GetTextAtEx to keep at least somekind of a speed with it): function GetText(XS, YS, XE, YE: Integer; var x, y: Integer; Tolerance, Chars, MinSpacing, MaxSpacing, TextColor, TextLength: Integer; Strict: Boolean; Range: Byte): string; var a: TBox; h, i: Integer; p: TPointArray; b: TSCARBitmap; c: TSCARClient; o: TPoint; t: string; begin if ((XS > XE) or (YS > YE) or (TextColor < 0) or (TextColor > 16777215)) then // To make sure coordinates are somewhat correct and also, the text color is valid. -1 color (all colors) doesn't work with this.. It would make this function very slow, but also hard to develop... Exit; if FindColorTolEx(p, TextColor, XS, YS, XE, YE, Tolerance) then // If any points matched with TextColor + Tolerance from XS, YS, XE, YE, then we CONTINUE... begin if ((XS <> 0) or (YS <> 0)) then o := Point((0 - XS), (0 - YS)); // We create an offset point, if XS or YS <> 0. a := TPABounds(p); // Area where the points were found.. if ((a.X1 - 10) > XS) then XS := (a.X1 - 10); // We do this just to gain some speed for searching/matching process. if ((a.Y1 - 10) > YS) then YS := (a.Y1 - 10); // We do this just to gain some speed for searching/matching process. b := TSCARBitmap.Create(''); try b.SetSize(((XE + o.X) + 1), ((YE + o.Y) + 1)); // Creating the bitmap for area to look for text. Background of the bitmap is black, matched points will be clWhite. h := High(p); for i := 0 to h do // We set all the matched points clWhite, that were found using TextColor + Tolerance. b.Pixels[(p[i].X + o.X), (p[i].Y + o.Y)] := clWhite; c := SetClient(TSCARBitmapClient.Create(b)); // We create a bitmap client for SCAR to look the text from.. try for x := XS to XE do begin for y := YS to YE do begin t := GetTextAtEx((x + o.X), (y + o.Y), Tolerance, Chars, False, False, MinSpacing, MaxSpacing, clWhite, TextLength, Strict, Range); if not StartsWith(' ', t) then // We make sure the text found at current position does NOT start with empty space. if (Length(Replace(t, ' ', '')) > (TextLength div 2)) then // To check that at least 50% of the matched text characters ARE NOT empty spaces. Result := t; // Result was found. if (Result <> '') then Break; // Breaking out when the text has been found. end; if (Result <> '') then Break; // Breaking out when the text has been found. end; if (Result = '') then begin x := -1; y := -1; end; finally SetClient(c).Free; // To free the bitmap client end; SetLength(p, 0); // Setting the p to 0, just so any memory wont leak. finally b.Free; // Freeing the area bitmap end; end; end; var x, y, SWFont: Integer; s: string; begin ClearDebug; GetClient.Activate; SWFont := LoadChars2(FontsPath + 'SWFont\'); s := GetText(0, 21, 500, 561, x, y, 0, SWFont, 0, 0, 16253176, 10, True, tr_AllChars); WriteLn('s: ' + s + ' [' + IntToStr(x) + ', ' + IntToStr(y) + ']'); FreeChars2(SWFont); end. Have fun with it guys! But do note that, it is not perfect at all... But at least it's a start, I guess. We can always improve it. Edited September 10, 2012 by Janilabo Quote Link to comment Share on other sites More sharing options...
LordJashin Posted September 10, 2012 Share Posted September 10, 2012 Hey mate, I have been thinking about ways to build the function.. But it's not the easiest thing to create, AT ALL... This is what I have came up with so far (uses currently SCAR's bugged GetTextAtEx to keep at least somekind of a speed with it): function GetText(XS, YS, XE, YE: Integer; var x, y: Integer; Tolerance, Chars, MinSpacing, MaxSpacing, TextColor, TextLength: Integer; Strict: Boolean; Range: Byte): string; var a: TBox; h, i: Integer; p: TPointArray; b: TSCARBitmap; c: TSCARClient; o: TPoint; t: string; begin if ((XS > XE) or (YS > YE) or (TextColor < 0) or (TextColor > 16777215)) then // To make sure coordinates are somewhat correct and also, the text color is valid. -1 color (all colors) doesn't work with this.. It would make this function very slow, but also hard to develop... Exit; if FindColorTolEx(p, TextColor, XS, YS, XE, YE, Tolerance) then // If any points matched with TextColor + Tolerance from XS, YS, XE, YE, then we CONTINUE... begin if ((XS <> 0) or (YS <> 0)) then o := Point((0 - XS), (0 - YS)); // We create an offset point, if XS or YS <> 0. a := TPABounds(p); // Area where the points were found.. if ((a.X1 - 10) > XS) then XS := (a.X1 - 10); // We do this just to gain some speed for searching/matching process. if ((a.Y1 - 10) > YS) then YS := (a.Y1 - 10); // We do this just to gain some speed for searching/matching process. b := TSCARBitmap.Create(''); try b.SetSize(((XE + o.X) + 1), ((YE + o.Y) + 1)); // Creating the bitmap for area to look for text. Background of the bitmap is black, matched points will be clWhite. h := High(p); for i := 0 to h do // We set all the matched points clWhite, that were found using TextColor + Tolerance. b.Pixels[(p[i].X + o.X), (p[i].Y + o.Y)] := clWhite; c := SetClient(TSCARBitmapClient.Create(b)); // We create a bitmap client for SCAR to look the text from.. try for x := XS to XE do begin for y := YS to YE do begin t := GetTextAtEx((x + o.X), (y + o.Y), Tolerance, Chars, False, False, MinSpacing, MaxSpacing, clWhite, TextLength, Strict, Range); if not StartsWith(' ', t) then // We make sure the text found at current position does NOT start with empty space. if (Length(Replace(t, ' ', '')) > (TextLength div 2)) then // To check that at least 50% of the matched text characters ARE NOT empty spaces. Result := t; // Result was found. if (Result <> '') then Break; // Breaking out when the text has been found. end; if (Result <> '') then Break; // Breaking out when the text has been found. end; if (Result = '') then begin x := -1; y := -1; end; finally SetClient(c).Free; // To free the bitmap client end; SetLength(p, 0); // Setting the p to 0, just so any memory wont leak. finally b.Free; // Freeing the area bitmap end; end; end; var x, y, SWFont: Integer; s: string; begin ClearDebug; GetClient.Activate; SWFont := LoadChars2(FontsPath + 'SWFont\'); s := GetText(0, 21, 500, 561, x, y, 0, SWFont, 0, 0, 16253176, 10, True, tr_AllChars); WriteLn('s: ' + s + ' [' + IntToStr(x) + ', ' + IntToStr(y) + ']'); FreeChars2(SWFont); end. Have fun with it guys! But do note that, it is not perfect at all... But at least it's a start, I guess. We can always improve it. Wow nice!!! You did a great job, lots of code written! I think I want to make some new bitmap functions, and etc for games. I'm tired of writing if FindBitmap lines. I need to learn how OSI's wait function works. Can some one explain that to me again. In the function that it is waiting on, does it wait until it returns true? I don't understand exactly... Quote Link to comment Share on other sites More sharing options...
Bixby Sayz Posted September 10, 2012 Share Posted September 10, 2012 (edited) I need to learn how OSI's wait function works. Can some one explain that to me again. In the function that it is waiting on, does it wait until it returns true? I don't understand exactly...Are you talking about WaitFunction? It's actually pretty straight forward once you get your head wrapped around it: [sCAR]function WaitFunc(Func: function: Boolean; DesiredResult: Boolean; MinWait, MaxWait, MinTotalWait, MaxTotalWait: LongInt): Boolean;[/sCAR] You pass in a function that takes no arguments and returns a Boolean result. You tell it what you are result waiting for (True or False) and every so often it will run the function, check the result, and if it matches yippee we are done! It will continue to do this periodically until the total time is reached, in which case it returns failure. MinWait and MaxWait are used to generate a randomized WaitTime of how often to execute the function and check it's result. If you don't want randomization make MinWait and MaxWait the same. Similar idea for MinTotalWait and MaxTotalWait are used to generate a random TotalWait (total time before giving up returning failure). Think of it something like this: repeat if Func() = DesiredResult then Success! otherwise Wait RandomRange(MinWait, MaxWait) until elapsed time = RandomRange(MinTotalWait, MaxTotalWait) So...WaitFunc(@LoginScreen, True, 25, 50, 5000, 6000) would execute the function LoginScreen() every 25..50 milliseconds. This will continue until LoginScreen() returns our desired result of True or 5000..6000 milliseconds have elapsed. Edit: WaitFuncEx allows you to call a function that takes parameters, but afaik it does not work. Edited September 10, 2012 by Bixby Sayz Quote Link to comment Share on other sites More sharing options...
EdithDag Posted September 18 Share Posted September 18 Many thanks. I appreciate this! next https://lawsocietytribunal.ca/licensee/caitlin-eloise-gossage/?referer=https://uscasinoguides.com/ his explanation sneak a peek at this web-site check over here https://busho-tai.jp/schedule/event_detail.php?eventname=New%20ab%20Description&url=https://uscasinoguides.com/ his response https://maps.google.cl/url?sa=t&source=web&rct=j&url=https://uscasinoguides.com/ you could look here https://www.thetriumphforum.com/proxy.php?link=https://uscasinoguides.com/ you can look here https://galant37.ru/bitrix/redirect.php?goto=https://uscasinoguides.com/ visit this site right here https://zaox.ru:443/redirect?url=https://uscasinoguides.com/ Quote Link to comment Share on other sites More sharing options...
MiltonSmure Posted September 21 Share Posted September 21 Гидроизоляция это ключевой элемент в строительстве, обеспечивающий охрану объектов от воздействия влаги и воды. В зависимости от условий эксплуатации и материала конструкции, выбирается определенный тип гидроизоляции. Рассмотрим основные разновидности и их применения. 1. Рулонные материалы Рулонные гидроизоляционные материалы используются для защиты кровель и фундаментов. Они бывают на основе битума и полимеров. - Битумные рулоны известны благодаря своей доступности и безопасности. Используются на плоских крышах и в основании зданий. - Полимерные рулоны имеют более высокую прочность и долговечность, подходят для трудных климатических условий. 2. Жидкая гидроизоляция Водянистые гидроизоляторы используются для создания бесшовного покрытия. Они посещают на основе: - Полимеров легко наносятся и образуют прочную мембрану. - Цемента совершенно то что надо для ванной и кухни, владеют превосходными гидрофобными свойствами. 3. Проникающая гидроизоляция Этот тип проникает в структуру бетона и наполняет микротрещины, обеспечивая надежную охрану. Применяется в большей степени для фундаментов и подвалов. Проникающая гидроизоляция отлично совладевает с постоянным воздействием воды. 4. Мембранная гидроизоляция Мембранные системы часто употребляются для крыши и подземных конструкций. Такой метод обеспечивает надежную защиту от осадков и грунтовых вод. - ЭПДМ и ТПО мембраны имеют высокую устойчивость к ультрафиолету и механическим повреждениям https://gidroizolyaciya-dlya-vsekh.ru 5. Гидрофобные добавки Гидрофобные добавки в бетон или раствор помогают предупредить проникновение влаги. Они идеально то что надо для создания водонепроницаемых конструкций, таких как бассейны и резервуары. Выбор типа гидроизоляции При выборе гидроизоляции важно учесть: - Правила использования влажность, температура, возможные нагрузки. - Материалы конструкции для каждого типа материала существует меня называют Господом лучший вариант гидроизоляции. - Бюджет некие методы более затратные, но дают обеспечение огромную долговечность. В заключение, выбор гидроизоляции зависит от множества факторов. Правильное решение поможет продлить срок службы строительных объектов и избежать суровых проблем с влажностью. Quote Link to comment Share on other sites More sharing options...
EdithDag Posted September 21 Share Posted September 21 You expressed that terrifically. advice https://velik.ru/bitrix/redirect.php?goto=https://uscasinoguides.com/ look at this website how you can help you can find out more http://zolotoi-mebelshchik.ru/bitrix/redirect.php?goto=https://uscasinoguides.com/ more about the author recommended site helpful site https://www.biounion.de/firmeneintrag-loeschen?nid=1&element=https://uscasinoguides.com/ try these out https://www.autokiste.de/kontakt/mailforms/leserbrief.htm?headline=Hyundai%20Kona:%20Erste%20Details,%20erste%20Bilder&id=12192&url=https://uscasinoguides.com/ you can check here use this link Quote Link to comment Share on other sites More sharing options...
MiltonSmure Posted September 21 Share Posted September 21 Гидроизоляция это ключевой элемент в строительстве, обеспечивающий защиту объектов от воздействия влаги и воды. В зависимости от условий эксплуатации и материала конструкции, выбирается определенный тип гидроизоляции. Рассмотрим главные разновидности и их применения. 1. Рулонные материалы Рулонные водоизоляционные материалы используются для защиты кровель и фундаментов. Они посещают на основе битума и полимеров. - Битумные рулоны популярны благодаря своей доступности и безопасности. Используются на плоских крышах и в основании зданий. - Полимерные рулоны имеют более высокую прочность и долговечность, то что надо для сложных климатических условий. 2. Жидкая гидроизоляция Жидкие гидроизоляторы применяются для творения бесшовного покрытия. Они посещают на основе: - Полимеров с легкостью наносятся и образуют прочную мембрану. - Цемента идеально подходят для ванной и кухни, обладают превосходными гидрофобными свойствами. 3. Проникающая гидроизоляция Этот тип проникает в структуру бетона и наполняет микротрещины, обеспечивая надежную защиту. Применяется предпочтительно для фундаментов и подвалов. Проникающая гидроизоляция эффективно совладевает с неизменным воздействием влаги. 4. Мембранная гидроизоляция Мембранные системы часто употребляются для крыши и подземных конструкций. Такой метод обеспечивает надежную защиту от осадков и грунтовых вод. - ЭПДМ и ТПО мембраны имеют высокую устойчивость к солнечному излучению и механическим повреждениям https://gidroizolyaciya-dlya-vsekh.ru 5. Гидрофобные добавки Гидрофобные добавки в бетон или раствор помогают предупредить проникновение воды. Они образцово подходят для творения водонепроницаемых конструкций, таких как бассейны и резервуары. Выбор типа гидроизоляции При выборе гидроизоляции главно учитывать: - Правила использования влажность, температура, вероятные нагрузки. - Материалы конструкции для каждого типа материала существует свой лучший вариант гидроизоляции. - Бюджет некоторые способы более затратные, но обеспечивают огромную долговечность. В заключение, выбор гидроизоляции зависит от множества причин. Правильное решение поможет продлить срок эксплуатации строительных объектов и избежать суровых проблем с влажностью. Quote Link to comment Share on other sites More sharing options...
EdithDag Posted September 22 Share Posted September 22 You reported this terrifically! navigate here redirected here click this link https://white-sign.ru/bitrix/redirect.php?goto=https://uscasinoguides.com/ top article https://therapy.school/bitrix/redirect.php?goto=https://uscasinoguides.com/ site here https://eshop.logictim.ru/bitrix/redirect.php?goto=https://uscasinoguides.com/ take a look at the site here https://avangard-eco.ru/bitrix/redirect.php?goto=https://uscasinoguides.com/ you could try here https://sibhunter22.ru/bitrix/redirect.php?goto=https://uscasinoguides.com/ check linked here Quote Link to comment Share on other sites More sharing options...
EdithDag Posted September 22 Share Posted September 22 Cheers. Awesome information. browse around here http://enotmebel.uz/bitrix/rk.php?goto=https://uscasinoguides.com/ here are the findings https://osheerus.ru/bitrix/rk.php?goto=https://uscasinoguides.com/ learn more http://medical-dictionary.tfd.com/_/cite.aspx?url=https%3A%2F%2Fuscasinoguides.com%2F&word=Dip%20Pract%20Derm&sources=hcMed you could try these out https://mineralx.ru/bitrix/redirect.php?goto=https://uscasinoguides.com/ what is it worth https://zgpc.ru:443/bitrix/redirect.php?goto=https://uscasinoguides.com/ view publisher site https://altaysnab.ru:443/bitrix/redirect.php?goto=https://uscasinoguides.com/ here https://lepnina.top/bitrix/rk.php?goto=https://uscasinoguides.com/ Quote Link to comment Share on other sites More sharing options...
Scottseize Posted September 26 Share Posted September 26 Он-лайн казино в Беларуси стали модным способом развлечений для большинства людей. Беря во внимание развитие технологий и доступность прибегают к помощи, азартные игры в сети привлекают все большее количество игроков. В этой статье мы рассмотрим характерные черты онлайн казино в Беларуси, их регулирование и перспективы развития этого сегмента. Законодательство и Регулирование В 2021 году Беларусь приняла ряд конфигураций в законодательство, касающиеся он-лайн-игр. Теперь онлайн казино подлежат лицензированию, что позволяет государству держать под контролем их деятельность и оберегать интересы игроков. Лицензии выдают специальные органы, обеспечивая прозрачность и безопасность игр. Игроки могут рассчитывать на защиту своих прав и легитимное регулирование азартных игр. Поэтому, выбор лицензированных онлайн казино становится более безопасным для юзеров. Популярность Онлайн Казино С увеличением энтузиазма к он-лайн азартным играм в Беларуси, многие известные международные операторы начали делать отличное предложение свои услуги. Игроки могут наслаждаться разнообразием игр, включая слоты, покер, рулетку и блэкджек. Огромное количество платформ делают отличное предложение интересные акции, призы и программы лояльности для вербования пользователей. Платежные Методы Онлайн казино в Беларуси предлагают различные способы пополнения счета и вывода средств. Знаменитыми методами являются банковские карты, электронные кошельки и криптовалюты. Удобство и скорость транзакций существенно упрощают игровой процесс и увеличивают уровень удовлетворенности игроков. Безопасность и Ответственная Забава С развитием онлайн казино возрастает и необходимость в обеспечении безопасности данных игроков. Лицензированные платформы используют современные технологии шифрования для защиты личной инфы и валютных средств пользователей. Не считая а всё потому великое внимание уделяется принципам ответственной забавы. Операторы предлагают приборы, которые подсобляют игрокам держать под контролем свое время и бюджет на азартные игры, снижая опасности зависимости. Перспективы Развития Будущее сделать ставку фрибет смотрится многообещающе. С ростом популярности азартных игр в социальных сетях и мобильных приложениях, ожидается, что количество пользователей будет только увеличиваться. Развитие технологий, таких как виртуальная и дополненная действительность, может изменить сферу онлайн-гейминга, предоставляя игрокам новые форматы веселий. Заключение Он-лайн казино в Беларуси совмещают в себе способности современных технологий и требования законодательства. Сохранение управления и контроля со стороны государства содействует развитию неопасной и ответственной игорной среды. При этом игрокам главно внимательно выбирать лицензионные платформы, что позволит им наслаждаться играми на деньги в комфортной и неопасной обстановке. Quote Link to comment Share on other sites More sharing options...