Thread View: borland.public.cppbuilder.nativeapi
20 messages
20 total messages
Started by Dan
Wed, 28 Feb 2007 15:04
Getting text from an external Grid
Author: Dan
Date: Wed, 28 Feb 2007 15:04
Date: Wed, 28 Feb 2007 15:04
11 lines
1347 bytes
1347 bytes
In previous messages I learned how to get test from external edit boxes or labels with GetWindowText or sending the WM_GETTEXT message to the appropriate handle. For external String Grids, those messages don't seem to work. Do I have to get a handle of an object within the stringgrid? Spy++ doesn't seem to find any other handle other than the grid. Am I using the wrong windows message? How can I retrieve text from an external process's stringgrid (actually it's a TxtListCtl per Spy++)?
Re: Getting text from an external Grid
Author: Remy Lebeau (TeamB)
Date: Wed, 28 Feb 2007 17:26
Date: Wed, 28 Feb 2007 17:26
31 lines
2014 bytes
2014 bytes
"Dan" <Dan@do.not.spam> wrote in message news:45e59a3a$1@newsgroups.borland.com... > For external String Grids, those messages don't seem to work. No, they do not. TStringGrid is a completely custom-written control. It does not provide any kind of external access at all, sorry. If you are trying to access a grid in a program that you wrote yourself, or have control of its source code, then you would have to implement your own access, such as by creating your own message (I would suggest basing it on WM_COPYDATA) that the parent form handles on the grid's behalf. > Do I have to get a handle of an object within the stringgrid? No, because there is none. > Spy++ doesn't seem to find any other handle other than the grid. Exactly. There is only one HWND available, and it is for the overall grid window. The text is not stored inside that HWND at all. It is stored in memory only, and then manually drawn onto the HWND's HDC when needed. > Am I using the wrong windows message? No. There simply aren't any available for grids in the first place. Gambit
Re: Getting text from an external Grid
Author: Dan
Date: Wed, 28 Feb 2007 18:52
Date: Wed, 28 Feb 2007 18:52
12 lines
1629 bytes
1629 bytes
> No. There simply aren't any available for grids in the first place. Oh fun... so, any suggestions? I have this third party application that I don't have code for, and the developer won't add any features to; and basically I just want to automate collection of data from it. I can automate data collection by sending windows messages to push specific buttons, but the total goal is to get data out of a grid (Spy++ has it as a TxtListCtl) and save it to a file and unfortunetly there aren't any features to facilitate getting the data to a file native to the app (thus why I was called)
Re: Getting text from an external Grid
Author: Remy Lebeau (TeamB)
Date: Wed, 28 Feb 2007 21:39
Date: Wed, 28 Feb 2007 21:39
16 lines
1298 bytes
1298 bytes
"Dan" <Dan@do.not.spam> wrote in message news:45e5cfa5$1@newsgroups.borland.com... > so, any suggestions? I have already given you my suggestion. > I have this third party application that I don't have code for, > and the developer won't add any features to Then you are out of luck, sorry. There is no external access available for grid controls. Gambit
Re: Getting text from an external Grid
Author: Dan
Date: Wed, 28 Feb 2007 22:05
Date: Wed, 28 Feb 2007 22:05
7 lines
1435 bytes
1435 bytes
How about this idea: I can get the color of each pixel in the object as it is displayed, and can basically repaint the object onto my own canvas. I could then export that as a bitmap or jpeg. Are there any components available that will take that data (in a bitmap or jpeg) and translate it into text? Like optical character recognition on a scanner?
Re: Getting text from an external Grid
Author: Remy Lebeau (TeamB)
Date: Wed, 28 Feb 2007 23:25
Date: Wed, 28 Feb 2007 23:25
20 lines
1726 bytes
1726 bytes
"Dan" <Dan@do.not.spam> wrote in message news:45e5fd07$1@newsgroups.borland.com... > I can get the color of each pixel in the object as it is displayed, > and can basically repaint the object onto my own canvas. > I could then export that as a bitmap or jpeg. There is an easier way. You can copy the entire contents of a HWND using GetWindowDC() and BitBlt(). You do not have to deal with the individual pixels. > Are there any components available that will take that data > (in a bitmap or jpeg) and translate it into text? Like optical > character recognition on a scanner? None from Borland. You would need third-party ones for that. Gambit
Re: Getting text from an external Grid
Author: Dan
Date: Thu, 01 Mar 2007 15:35
Date: Thu, 01 Mar 2007 15:35
26 lines
2516 bytes
2516 bytes
> There is an easier way. You can copy the entire contents of a HWND > using GetWindowDC() and BitBlt(). You do not have to deal with the > individual pixels. Humm.. I'll have to look at that; I had to use GetWindowDC to be able to access the pixels; didn't see BitBlt(). I did have three problems here though: (1) I couldn't access the pixels unless the dialog I was copying was visibly on the screen; I was using the ShowWindow(MainWindow,SW_SHOWNORMAL); command to make the 'MainWindow' (a handle to the application I was copying) visible; however, it didn't bring it to the front and therefore the pixel grabbing didn't always work. Is there a way to get the target application 'On Top' always, or a better way to grap the pixels that will work even if the target app is off screen, behind something else, or minimized? (2) I couldn't find a clear way to get the height and width, in pixels, of the target I was copying. Is there a way to grab the height in pixels of the target handle or DC? (3) The OCR library I found didn't do that great of a job using just the screen image copied pixel by pixel, therefore to get the OCR to work better, I had to enlarge the image by a factor of two. I guess this isn't a problem so much with the nativeapi; however, if anyone has ideas for 1 and 2 above, I hope that the solution keeps in mind that I will then have to scale the image up, potentially, so that OCR works.
Re: Getting text from an external Grid
Author: Bob Gonder
Date: Thu, 01 Mar 2007 17:14
Date: Thu, 01 Mar 2007 17:14
22 lines
1863 bytes
1863 bytes
Dan wrote: >(1) I couldn't access the pixels unless the dialog I was copying was >visibly on the screen; You might try BringWindowToTop( hWnd ) >(2) I couldn't find a clear way to get the height and width, in pixels, >of the target I was copying. Is there a way to grab the height in >pixels of the target handle or DC? W = GetDeviceCaps( hDC, HORZRES ); H = GetDeviceCaps( hDC, VERTRES ); See the topic "Capturing an Image" in the BCB/BDS helps >(3), I had to enlarge the image by a factor of two. See the very next topic: "Scaling an Image" Basically, besides adjusting the size of the created bitmap, you use StretchBlt instead of BitBlt to capture the image.
Re: Getting text from an external Grid
Author: Dan
Date: Thu, 01 Mar 2007 19:05
Date: Thu, 01 Mar 2007 19:05
10 lines
1536 bytes
1536 bytes
> W = GetDeviceCaps( hDC, HORZRES ); > H = GetDeviceCaps( hDC, VERTRES ); Seems to get the Application size, not the actual component (eg. label) size. > Basically, besides adjusting the size of the created bitmap, you use > StretchBlt instead of BitBlt to capture the image. True,.. but this only works if I know the size of the component :)
Re: Getting text from an external Grid
Author: Remy Lebeau (TeamB)
Date: Thu, 01 Mar 2007 20:11
Date: Thu, 01 Mar 2007 20:11
14 lines
1520 bytes
1520 bytes
"Dan" <Dan@do.not.spam> wrote in message news:45e72444$1@newsgroups.borland.com... > Seems to get the Application size, not the actual component (eg. label) > size. Which HWND are you passing to GetWindowDC()? The main window or the grid's window? Since you are only intereste in the grid, you should be using its HWND for everything. Gambit
Re: Getting text from an external Grid
Author: Dan
Date: Thu, 01 Mar 2007 20:42
Date: Thu, 01 Mar 2007 20:42
33 lines
2716 bytes
2716 bytes
> Which HWND are you passing to GetWindowDC()? The main window or the > grid's window? Since you are only intereste in the grid, you should > be using its HWND for everything. > I'm using the HWND for the grid. In my 'CopyObject' routine that graphically copies the HWND I want (or the grid), I am doing the following: HANDLE HandleToTheGrid = HANDLE(HexIdOfGrid); if (HandleToTheGrid==NULL) return; HDC DCToTheGrid= GetWindowDC(HandleToTheGrid); //this displays the app that has the Grid ShowWindow(TheHandleToTheApp,SW_SHOWNORMAL); int w = GetDeviceCaps(DCToTheGrid, HORZRES); int h = GetDeviceCaps(DCToTheGrid, VERTRES); //then, basically I can fill a TImage, pixel by pixel.. (whoohoo) Unfortunetly, w and h are always the same, and equal to the application. However, interestingly, the image of the grid, does start at pixel 0,0 and correctly corresponds to the grid I want and doesn't include any other GUI items. So rather than calling GetDeviceCaps, right now, I am simply hardcoding worst cases; which results in extraordinarily slow code obviously. To get pixels, I am looping from 0 to height within a 0 to width loop where I get the color of the pixel with GetPixel(DCToTheGrid,x,y); and then paint it to a TImage using ImageClassPointer->Canvas->Pixels[x][y] = c; Better ways are welcome.
Re: Getting text from an external Grid
Author: Remy Lebeau (TeamB)
Date: Thu, 01 Mar 2007 21:12
Date: Thu, 01 Mar 2007 21:12
33 lines
2212 bytes
2212 bytes
"Dan" <Dan@do.not.spam> wrote in message
news:45e73ae4@newsgroups.borland.com...
> HANDLE HandleToTheGrid = HANDLE(HexIdOfGrid);
What is HexIdOfGrid?
> Unfortunetly, w and h are always the same, and equal to the
> application.
Then you are not using the correct HDC.
Try using GetWindowRect() instead, using the grid's HWND.
> To get pixels, I am looping from 0 to height within a 0 to width
loop
> where I get the color of the pixel with GetPixel(DCToTheGrid,x,y);
> and then paint it to a TImage using
ImageClassPointer->Canvas->Pixels[x][y]
> = c;
Again, you do not need to access the individual pixels. Once you have
a suitable HDC, you can BitBlt() or StretchBlt() the entire window to
a bitmap, and then use that as needed. For example:
ImageClassPointer->Picture->Bitmap->Width = width;
ImageClassPointer->Picture->Bitmap->Height = height;
::BitBlt(ImageClassPointer->Canvas->Handle, 0, 0, width, height,
DCToTheGrid, 0, 0, SRCCOPY);
Gambit
Re: Getting text from an external Grid
Author: Dan
Date: Thu, 01 Mar 2007 22:16
Date: Thu, 01 Mar 2007 22:16
23 lines
2168 bytes
2168 bytes
> What is HexIdOfGrid? The result of a FindWindowEx(...) function that identified the handle of the grid I was looking for. > Try using GetWindowRect() instead, using the grid's HWND. GetWindowRect yields the same results. > Again, you do not need to access the individual pixels. Once you have > a suitable HDC, you can BitBlt() or StretchBlt() the entire window to > a bitmap, and then use that as needed. For example: Forgive my frustration, but oh, I've tried, what's wrong with this code?: BitBlt(GetWindowDC(TheTImagePointer->Canvas->Handle),0,0,w,h,DCToTheGrid,0,0,PATCOPY); It doesn't copy anything. >>>Then you are not using the correct HDC. I find it hard to belive that I am using the incorrect HDC, since the GetPixel(DCToTheGrid,x,y); call returns the correct color for each pixel, allowing me to copy the beast.
Re: Getting text from an external Grid
Author: Remy Lebeau (TeamB)
Date: Thu, 01 Mar 2007 22:34
Date: Thu, 01 Mar 2007 22:34
30 lines
2161 bytes
2161 bytes
"Dan" <Dan@do.not.spam> wrote in message news:45e75113$1@newsgroups.borland.com... > > > What is HexIdOfGrid? > > The result of a FindWindowEx(...) function that identified the handle of > the grid I was looking for. Why are you casting it to a HANDLE? FindWindowEx() returns an HWND, and GetWindowDC() expects an HWND. > Forgive my frustration, but oh, I've tried, what's wrong with this code?: > > BitBlt(GetWindowDC(TheTImagePointer->Canvas->Handle),0,0,w,h,DCToTheGr id,0,0,PATCOPY); > > It doesn't copy anything. Look at that code, and compare it with the code I gave you in my last reply. See anything different? Your first parameter is wrong, so the function is failing. The TCanvas::Handle property is not an HWND. It is an HDC, so use it as-is. Also, why are you using PATCOPY? You are not copying a pattern. Gambit
Re: Getting text from an external Grid
Author: Dan
Date: Fri, 02 Mar 2007 14:42
Date: Fri, 02 Mar 2007 14:42
7 lines
1707 bytes
1707 bytes
Well.. I have changed the code from HANDLE to HWND; same results. I'll take a step back and look to see if I have made any other obvious errors. On another note: Will I have the same problem with a MenuItem type control? Is there a way to automate that from an external app?
Re: Getting text from an external Grid
Author: Remy Lebeau (TeamB)
Date: Fri, 02 Mar 2007 17:48
Date: Fri, 02 Mar 2007 17:48
18 lines
2010 bytes
2010 bytes
"Dan" <Dan@do.not.spam> wrote in message news:45e83813$1@newsgroups.borland.com... > Well.. I have changed the code from HANDLE to HWND; same results. Did you notice the other change I pointed out? > Will I have the same problem with a MenuItem type control? > Is there a way to automate that from an external app? Menus are much easier to automate, as there are several menu-related window messages available. The easiest one is to simply send WM_COMMAND to the menu's parent window, specifying the ID of the item you wish to execute. You don't need to actually drop the menu down and select the item manually beforehand. Gambit
Re: Getting text from an external Grid
Author: Dan
Date: Fri, 02 Mar 2007 19:19
Date: Fri, 02 Mar 2007 19:19
17 lines
2220 bytes
2220 bytes
>>>>> The easiest one is to simply send WM_COMMAND Thanks! When I send this message, I can get a FileSave Dialog to appear, but the dialog appears to be modal, in so much that after I send the above message, control doesn't resume to the next line in my code until the dialog is closed. Can I get around that by placing the SendMessage in another thread? Is there a way to get around this? I tried creating another thread that would monitor to see if the FileSave Dialog appeared, and if so, then take some action... but that thread too doesn't seem to get any action until the dialog is closed. Does that sound right? Or am I yet again doing something wrong?
Re: Getting text from an external Grid
Author: Dan
Date: Fri, 02 Mar 2007 19:21
Date: Fri, 02 Mar 2007 19:21
20 lines
2228 bytes
2228 bytes
Dan wrote: > >>>>> The easiest one is to simply send WM_COMMAND > > Thanks! > > When I send this message, I can get a FileSave Dialog to appear, but the > dialog appears to be modal, in so much that after I send the above > message, control doesn't resume to the next line in my code until the > dialog is closed. > > Can I get around that by placing the SendMessage in another thread? > Is there a way to get around this? > > I tried creating another thread that would monitor to see if the > FileSave Dialog appeared, and if so, then take some action... but that > thread too doesn't seem to get any action until the dialog is closed. > > Does that sound right? Or am I yet again doing something wrong? Oh,.. maybe PostMessage will work?
Re: Getting text from an external Grid
Author: Dan
Date: Fri, 02 Mar 2007 19:26
Date: Fri, 02 Mar 2007 19:26
3 lines
1572 bytes
1572 bytes
> Oh,.. maybe PostMessage will work? Never mind,.. yes PostMessage works fine.
Re: Getting text from an external Grid
Author: Remy Lebeau (TeamB)
Date: Fri, 02 Mar 2007 20:00
Date: Fri, 02 Mar 2007 20:00
27 lines
2272 bytes
2272 bytes
"Dan" <Dan@do.not.spam> wrote in message news:45e87917$1@newsgroups.borland.com... > When I send this message, I can get a FileSave Dialog to appear, but > the dialog appears to be modal, in so much that after I send the above > message, control doesn't resume to the next line in my code until the > dialog is closed. That is because the dialog is displayed in the context of the message handler. SendMessage() can't return until the message handler exits. Try using PostMessage() instead of SendMessage() if you need your code to continue immediately. > Can I get around that by placing the SendMessage in another thread? Yes. > Is there a way to get around this? You could alternatively use SendMessageTimeout() instead of SendMessage(). Gambit
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads