How can I make my C++ ActiveX control print nicely in Excel? - c++

I am trying to get my ActiveX control to print out nicely in Excel.
The control is written in C++. Originally I generated the control using the Visual Studio 2005 wizard. I have tested this with a simple wizard generated control to experiment with the OnDraw function and I discovered that even a control straight out of the wizard doesn't print well either. It appears to clip out a large portion of the control - which by default renders a black outline and some text in the centre.
The function IDataObject_GetData is called on my ActiveX control which in turn creates a metafile and renders to it.
Does anyone know how to get an ActiveX control to print out nicely? Alternatively links to useful information will be appreciated.

After much head scratching I figured out the solution to my problem.
The OnDraw function generated by the Visual Studio 2005 wizard sets up a clipping region by calling the function SelectClipRgn. It was this clipping setup that was causing ActiveX control to appear clipped when printed. Commenting out the code makes the ActiveX control print out perfectly. Commenting out the code doesn't appear to cause any other problems either - at least not in my case.
I can only assume that whatever coordinate system is used for clipping is not compatible with the coordinate system used when drawing to a metafile DC.
Here are some links to useful info that I found about printing ActiveX controls:
http://www.codeproject.com/KB/COM/officeatlprint.aspx
http://www.codeproject.com/KB/COM/WirgerPrintArticle.aspx
http://support.microsoft.com/kb/81497
http://support.microsoft.com/kb/84984

Related

Drawing text over/in a Process/Game

I'm currently working on a C++ DLL project.
This DLL will be injected into a game.
All I'm looking to do for now is draw some text like "Active" or "Working" in the bottom right or left hand corner of the screen when in game.
Just to give me something visual to show that the DLL is working and active/injected.
I haven't done this myself and this is an amalgamation of resources. First of all, since you're targeting GTA San Andreas, you should know that it's running using DirectX 9. I'm not aware of any OpenGL rendering version, so correct me if I'm wrong. Now about how to 'inject' make a draw call to render an overlay, please look in here: Hooking DirectX EndScene from an injected DLL. So, basically you change DirectX function EndScene() with your custom function that draws the text you need and then calls the actual EndScene(). Let me know if you want to know more.
Helpful links:
Draw text in Direct3D 9
What is the most efficient way to draw text in DirectX 9?

vs2010: Gradient background in a windows application

I am working on visual studios 2010 and c++. I am trying to change the background color of my basic windows app i want to put gradient colors to it like how skype and other programs do is it possible? As far as my guess is that i have to add gradient brush on the WNDCLASSEX.hbrBackground so far i could only find this
http://msdn.microsoft.com/en-us/library/windows/desktop/dd371488%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dd799414%28v=vs.85%29.aspx
But i could not make it work as a whole background, i am just making guesses as i am completely lost and an example code or description on how to achieve this will be really helpful.
If you want to support versions prior to Vista, you needed to handle WM_ERASEBKGND message in your window proc and do the whole painting of the background yourself. Read about GDI or GDI+ at msdn on how to do it.

How to change button color?

I am developing a GUI application using Embarcadero VCL c++ IDE for windows OS. As part of this project, I have to change color of button with respect to an external state.
I understood that windows32 API will not allow to change the color of button.
Could you please suggest me, how to change button color?
Do you wish to change the background-colour of the button, or the text-colour of it?
Since windows has used visual themes for some time now, if you have commctrl loaded and include a manifest file, the button will be drawn using the default (current) theme.
Options I can see include (a) custom-drawing the background (b) changing the text-colour in the normal draw process (c) drawing the button without a theme (i.e drawing a 'flat' button).
You could simply draw a bitmap-button, changing the bitmap depending on the state of the button. You could also use a single bitmap, tinting it using the HSL or HSV colour-space, depending on the state.
As for the flat type of button, I think you can probably change it's background-colour in much the same way as you can change the colour of the text - by intervening during the standard draw process and changing the colour from 3D_FACE (or whatever it is, I forget) to whatever you'd like.
If you look at the calculator included with windows XP, you can see an example of changing the text colour.
CodeProject.com likely has a stack of articles that would help in this endeavour. :)

C++ - How to screen-capture, except for some windows

Situation: I have a software that performs screen sharing over the Internet, where one user acts as a presenter, and other users act as viewers/attendees.
Besides the presentation windows, the presenter also has a set of NON-SHARING-WINDOWS that appear on the screen (a button bar for start sharing/stop sharing/etc., a Skype window etc.).
The presenter can configure from the setup of the screen sharing software to make these NON-SHARING-WINDOWS invisible (i.e. they will not appear in the screen sharing that is being sent to the attendees, but the window content behind them will appear in the screenshot).
The screenshots are sent at approximately 10 frames-per-second, or faster.
Question: how can I programmatically capture the screen, except for these NON-SHARING-WINDOWS windows?
Notes:
Because of the higher frames-per-second value, I cannot minimize/maximize/set alpha for these windows, because then the windows will flicker. The application is written in Win32 C++.
I would use layered windows, but because of the Windows 7 Desktop Composition feature, this is not usable out-of-the-box (and in Windows 8, you cannot use DwmEnableComposition anymore to temporarily and programmatically disable composition)
I could use the layered window approach for Windows XP/2000/7 etc., and a different approach for Windows 8 (if there is one), though I would prefer a single process that works on all systems
I could also try to "compose" the screenshots by capturing individual images (of the desktop, the windows that need to be captured) and using their z-index to create the final image, but because of the required frames-per-second value, this process would be too slow.
In windows even the desktop is considered a window and has its own HWND.
It seems however, not easily possible to only copy the "wallpaper" on its own.
So i basically see two ways to do that.
1. Copy the entire desktop e.g. BitBlt(GetWindowDC(GetDesktopWindow()),...)
OR
Use GetWindow and traverse the window list in backward direction starting from the Desktop-Window whose HWND you just can determine with GetDesktopWindow(), Like this:
// paint on a black DC
hwnd=GetDesktopWindow()
while (hwnd = GetWindow(hwnd, GW_HWNDPREV))
{
// is this window not shared? continue
// else bitblt it into our dc
}
Hope i gave some inspiration :-)
If someone knows a way how to copy ONLY the desktop without its child windows please let me know.
You can use Magnifier API.
There is a function in magnifier API that allows you to exclude specific windows from your target window (your window with 1x magnification where magnifier renders).
You can set this window to full screen and make it transparent and then use PrintWindow function.
The function: https://learn.microsoft.com/en-us/windows/desktop/api/magnification/nf-magnification-magsetwindowfilterlist
Sample projects:
https://www.codeproject.com/Articles/607288/Screenshot-using-the-Magnification-library
https://code.msdn.microsoft.com/windowsdesktop/Magnification-API-Sample-14269fd2
I'm aware this question is pretty old, but I ran into the same problem and it was very, very hard to find any information at all regarding this.
Since Windows 10 version 2004 (build 10.0.19041), the SetWindowDisplayAffinity API has been expanded to include a flag called WDA_EXCLUDEFROMCAPTURE (0x00000011). This will remove the window from images captured with BitBlt
The window is displayed only on a monitor. Everywhere else, the window does not appear at all.
One use for this affinity is for windows that show video recording controls, so that the controls are not included in the capture.
Introduced in Windows 10 Version 2004. See remarks about compatibility regarding previous versions of Windows.
For versions before 2004, it will use the existing WDA_MONITOR flag.
I have tested this with a screen capture of the desktop and I am unsure what would happen if you were to use a window DC.
So I guess a possible solution would be:
// get window handle
hWnd = (...)
BOOL result = SetWindowDisplayAffinity(m_hWnd, WDA_EXCLUDEFROMCAPTURE);
// do bitblt stuff
mabye you can use Magnification API, even Microsoft said The MagImageScalingCallback function is deprecated in Windows 7 and later, and should not be used in new applications. There is no alternate functionality., but it still work on Windows 10;
Here is the overview of this API : https://learn.microsoft.com/en-us/previous-versions/windows/desktop/magapi/magapi-intro
The sample code of Microsoft is here : https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Magnification
If you want to get the screenshot rgb data, you can use this api MagSetImageScalingCallback to set callback of Magnifier window, every time you use MagSetWindowSource or InvalidRect of magnifer window, this callback function MagImageScalingCallback will be called, so you can get screenshot rgb data here.
I think that to limit the capture content within a big window will be more simple. otherwise you will need to cut some windows from the screen capture.

Screen capture of MDI app with OpenGL graphics using MFC

In our MDI application - which is written in MFC - we have a function to save a screenshot of the MDI client area to file. We are currently doing a BitBlt from the screen into a bitmap, which is then saved. The problem is that some of the MDI child windows have their content rendered by OpenGL, and in the destination bitmap these areas show up as blank or garbled.
I have considered some alternatives:
- Extract the OpenGL content directly (using glReadPixels), and draw this to the relevant portions of the screen bitmap.
- Simulate an ALT+PrtScr, since doing this manually seems to get the content just fine. This will trash the clipboard content, though.
- Try working with the DWM. Appart from Vista and Win7, this also needs to work on Win2000 and XP, so this probably isn't the way to go.
Any input will be appreciated!
The best way to get a bitmap from an OpenGL window is to draw the content to a bitmap 'window'. See PFD_DRAW_TO_BITMAP for more information on how to do this.
If you want to go with the Alt+PrtScr way, you have to consider that many users have their own print screen tool installed which reacts on that very same hotkey. So you can't be sure that this hotkey will copy the content to the clipboard. It may just open the window of the installed print screen tool/utility.
Use the glReadPixels() approach. This question is asked quite often, here, on the gamedev.net forums and on other places, so google should show you code samples easily, but the glReadPixels() approach is the generally recommended approach.
Simulating keypresses is a recipe for disaster, I would stay away from that.