How to get IWebBrowser2's update rect? - c++

I am using IWebBrowser2 control to convert html into a bitmap in a win32 program, which I have succeeded doing it. I Draw the whole page all the time, which is not efficient way to do.
So it will be very good to know the update area, so that each time I can only draw the update rect. But I have not found any way to do so.
I did rendering flash before, and I can get dirty rect from IOleInPlaceSiteWindowless::InvalidateRect(LPCRECT pRect, BOOL), while IWebBrowser does have a window and does not have this interface.
What to do to get the dirty rect? Thank you inadvance!!

I think GetUpdateRgn is the function you are looking for. It returns the currently invalidate region.

Related

Taking a screenshot, analyzing it, then deleting it

I've been trying to code an auto clicker for a simple game online (a php coded one), but I've had trouble analyzing the colors on-screen. (English isn't my first language, sorry!) I've already done a bit of C++ in university, but only for science-oriented simple console programs. (Edit: I'm working on windows!! forgot to mention)
I've already tried the getpixel function, but since my chrome window is zoomed out at 80% to get the full game in frame, it seems I'm having some DPI related issues, but looking into this made my head dizzy.
After watching a Codebullet video, I thought a better approach to this would be to take a screenshot of the problematic area, analyze it to see if the condition is filled, then delete the screenshot. The problem is, I have no idea how I could achieve this and Google didn't help much this time :\
My code is extremely messy so I can't show it right now, but it's basically just a:
-click there
-click there after 5 seconds
-click there if this pixel is this color
-repeat
Is there an easy answer to this? I'd be really thankful if there is. Have a nice day! :)
You don't need to save the screen shot if you don't want to:
Pass the target window handle to GetDC(), t will return the the device context of the window.
Pass the device context to CreateCompatibleDC() to create a compatible DC.
Use CreateCompatibleBitmap(), passing in the DC and the size of the window. This returns a handle to a bitmap
Use SelectObject() to select the bitmap
Use BitBlt() to do a bitblock transfer of the selected pixels from the regular DC into the compatible DC using the SRCCOPY raster operation code to do a normal copy.
Create a BITMAP object. Use GetObject() and pass the handle to the bitmap you created.
Create a BITMAPINFOHEADER and define the member vars. Create an array of unsigned chars big enough to fit all the pixels from your bitmap.
Use GetDIBits() passing in the handle to the compatible bitmap, the bitmap header and a pointer to the pixel array. This loads the pixels from the bitmap into the pixel array.
Now parse all that juicy pixel data, search for the colors you're looking for and test the results against your conditionals to decide what to do next.
Don't forget to delete objects and release memory & device contexts.
I believe this is the tutorial I followed where I learned this, courtesy of MSDN: https://learn.microsoft.com/en-us/windows/desktop/gdi/capturing-an-image

Need a way to display image and draw on the image in Visual C++

The current way that I found was to make a bitmap and paint it into a picturebox,
but there it is very slow when trying to scroll the panel (the picturebox is inside a scrollable panel).
Is there a better way to achieve this functionality?
Load the bitmap only when your picture box is created, then leave it in memory until the picture box is destroyed. Loading the bitmap every time OnPaint is called will destroy performance.
Also make sure you aren't re-painting your bitmap if you receive a WM_PAINT message and nothing has changed.
That image size, 1500x2000 will be slow. How about resizing it to 25% to show a preview and if a user wishes to see the whole image give them an alert it may take some time.

Function to retrieve the size of an element

What I need is a function to retrieve the size of an element, be it a Java Applet window in a browser, text boxes in programs, applications window and so on.
Now I don't know what this kind of function is called, but I uploaded an example from an application that had that functionality.
Example (The red box)
What I need to be able to with this is get its size and its coordinates on the screen. This needs to be in C++.
So ff anyone could give an example, or atleast the name of that kind of function, I would be grateful.
I found a program that has the function I seek: It is called Scar Divi, which is a scriptable tool to perform repetitive actions, mostly uses for cheating in a game called Runescape it seems. Unfortunately it is closed source.
Are you looking for Window Geometry or desktop widget?
After getting an image of the screen (there will be somethign in Qt to do this)
You need an image processing library like openCV to find the rectangle - look for "Hough Transform"
I found the solution!
POINT p;
HWND wnd;
RECT rec;
GetCursorPos(&p);
wnd = WindowFromPoint(p);
GetWindowRect(wnd, &rec);
This will give you the coordinates for the box (extract from rec).

Custom draw button using uxtheme.dll

I have implemented my custom button inheriting from CButton and drawing it by using uxtheme.dll (DrawThemeBackground with BP_PUSHBUTTON).
Everything works fine but I have two statuses (Normal and Pressed) which Hot status is the same. It means when the user places the cursor over the button it is drawn alike regardless the button status (Pressed or not).
This is a bit confusing to the user and I would like to change the way the button is drawn in Pressed & Hot status. Does anybody know a way?
I have also thought about custumizing the whole drawing but the buttons use gradients, borders, shadows, etc. So it is not easy to achive the same look&feel drawing everything by myself. Is there a way to find the source code of the dll or know how to do it?
Thanks in advance.
Javier
Note: I think I could be able to achive what I want to do by using CMFCButton and overriding the OnDraw method. Let the control draw the button on OnDrawBorder and then drawing the inside button myself. But I need to know how the control draws the inside button when pressed. It is a gradient and I can't guess how it's done. Does anybody have a clue?
In answer to your second question, if you derive from CMFCButton instead of CButton you can override OnDraw() or OnDrawText() instead of the usual DrawItem(). That way the default button background will be drawn, and then your drawing code is executed.
The only way I know of to really tackle this is to use 'custom draw', rather than 'owner draw'. Custom draw came in with Windows 2000, but is only used by button controls with comctrl32 6.0 (so Windows XP onwards), isn't very clearly documented, and isn't something MFC goes out of its way to support.
Anyway, the good thing about custom draw is that it lets you hook in at various points in the drawing process, unlike owner draw, which makes you deal with the whole thing. Have a look in MSDN at the NM_CUSTOMDRAW notification message.
For the other part of your problem, detecting the 'hot' state, the easiest way to do this is to use WM_MOUSEMOVE messages and the TrackMouseEvent() function to track whether the mouse is over your button.
Unfortunately this is a bit of a vague answer: the amount of code you need to demonstrate a button that uses custom draw is a bit too much to type into these answer boxes! I do have a project that demonstrates such techniques, using a custom draw button (falling back to owner draw on older Windows versions) that adds a little arrow to the button. You can have a look at the source code by getting
Windows_UI_source.zip
Open it and have a look at the "DropArrowButton" class. The important bit is the OnCustomDraw() handler and its helper function DrawControl(): these get called at the various button drawing phases, and use UxTheme to draw the control appropriately.
I finally figured out how to achive what I want to do. It's pretty easy indeed.
I use two calls to DrawThemeBackground. The first one with PBS_PRESSED and the second one with state PBS_HOT. Then I make a ExcludeClipRect to avoid from drawing over the center of the button.
Something like this:
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_PRESSED,
&pCustomDraw->rc,
NULL);
CDC *pDC = CDC::FromHandle(pCustomDraw->hdc);
CRect rectClient;
GetClientRect(rectClient);
CRect rectInternal = rectClient;
rectInternal.DeflateRect(4,4);
pDC->SelectClipRgn(NULL);
pDC->ExcludeClipRect(&rectInternal);
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_HOT,
&pCustomDraw->rc,
NULL);
pDC->SelectClipRgn(NULL);
Of course this is not the whole code but I think is enough to make my point.
Thanks.

How to fix an MFC Painting Glitch?

I'm trying to implement some drag and drop functionality for a material system being developed at my work. Part of this system includes a 'Material Library' which acts as a repository, divided into groups, of saved materials on the user's hard drive.
As part of some UI polish, I was hoping to implement a 'highlight' type feature. When dragging and dropping, windows that you can legally drop a material onto will very subtly change color to improve feedback to the user that this is a valid action.
I am changing the bar with 'Basic Materials' (Just a CWnd with a CStatic) from having a medium gray background when unhighlighed to a blue background when hovered over. It all works well, the OnDragEnter and OnDragExit messages seem robust and set a flag indicating the highlight status. Then in OnCtrlColor I do this:
if (!m_bHighlighted) {
pDC->FillSolidRect(0, 0, m_SizeX, kGroupHeaderHeight, kBackgroundColour);
}
else {
pDC->FillSolidRect(0, 0, m_SizeX, kGroupHeaderHeight, kHighlightedBackgroundColour);
}
However, as you can see in the screenshot, the painting 'glitches' below the dragged object, leaving the original gray in place. It looks really ugly and basically spoils the whole effect.
Is there any way I can get around this?
Remote debugging is a godsend for debugging visual issues. It's a pain to set up, but having a VM ready for remote debugging will pay off for sure.
What I like to do is set a ton of breakpoints in my paint handling, as well as in the framework paint code itself. This allows you to effectively "freeze frame" the painting without borking it up by flipping into devenv. This way you can get the true picture of who's painting in what order, and where you've got the chance to break in a fill that rect the way you need to.
It almost looks like the CStatic doesn't know that it needs to repaint itself, so the background color of the draggable object is left behind. Maybe try to invalidate the CStatic, and see if that helps at all?
Thanks for the answers guys, ajryan, you seem to always come up with help for my questions so extra thanks.
Thankfully this time the answer was fairly straightforward....
ImageList_DragShowNolock(FALSE);
m_pDragDropTargetWnd->SendMessage(WM_USER_DRAG_DROP_OBJECT_DRAG_ENTER, (WPARAM)pDragDropObject, (LPARAM)(&dragDropPoint));
ImageList_DragShowNolock(TRUE);
This turns off the drawing of the dragged image, then sends a message to the window being entered to repaint in a highlighted state, then finally redraws the drag image over the top. Seems to have done the trick.