Draw text on screen C++ - c++

I want to draw text on the screen above all the windows.
I found out about HDC and start working with it. I had 2 problems: the text was flashing and there was background. I found out the function:
SetBkMode(hdc, TRANSPARENT);
but all it done is cancel the flashing. I still got background. My final code now is:
RECT rect = { 20, 20, 200, 200 };
SetTextColor(hdc,RGB(255,0,0));
SetBkMode(hdc, TRANSPARENT);
SetBkColor(hdc,RGBA(0,255,0,0));
DrawText(hdc, L"My text",-1,&rect,DT_LEFT);
I put this code in while(true) statement and sleep for 1 millisec.
Before the while i got the hdc init:
HDC hdc = GetDC(0);
So at this point i got non flashing text but with background (not transparent).
The background is half transparent so i can see what below it but it doesn't update. When i put a new window below it i can see the "background" of the old one.
I tried using wndproc like in this question:
How to draw text with transparent background using c++/WinAPI?
But it does nothing at all (i cant even see the text)
I tried using the textout example from msdn site:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145133(v=vs.85).aspx
But it does nothing too.
How can i draw text on the screen without background at all?
Thank you guys

Related

How can I paint a rectangle around a window without overriding the title bar in win32

I want to draw a rectangle around my window but I don't want to override the title bar.
what I wrote so far in the window callback function is:
case WM_NCPAINT:
{
HDC hdc;
RECT rect;
HPEN pen;
hdc=GetDCEx(hWnd,(HRGN)wParam,DCX_WINDOW|DCX_CACHE|DCX_INTERSECTRGN|DCX_LOCKWINDOWUPDATE);
GetWindowRect(hWnd,&rect);
pen=CreatePen(PS_SOLID, 10, RGB(255, 0, 0));//red pen 10 pixels in size
SelectObject(hdc,pen);
Rectangle(hdc,0,0,(rect.right-rect.left),(rect.bottom-rect.top));
DeleteObject(pen);
ReleaseDC(hWnd,hdc);
}
break;
However, this draws over the window title bar with white brush.
How can I make it not to paint over the title bar? I'm loosing the title bar text and the menu...
I have tried using HOLLOW_BRUSH before creating the pen as follows:
HBRUSH b=CreateSolidBrush(HOLLOW_BRUSH);
SelectObject(hdc,b);
But that only caused the title bar to not be drawn at all (being black).
By handling the WM_NCPAINT message, you are telling the window manager that you are taking responsibility for painting the entire non-client area, and so the window manager will not draw any of it for you.
If you want the original title bar to be drawn then you need to call DefWindowProc() first, then do your own drawing "on top" of what it draws.
You may also need to use ExcludeClipRect() to prevent the client area from being drawn over if you wish to draw the entire non-client area at once with a single rectangle.

PrintWindow causes flicker, strange artifacts in titlebar

I'm trying to take a screenshot of a Chrome window. It looks like this:
When I use PrintWindow to get the screenshot, I can see a flicker on the window titlebar/Chrome tab area. The captured screenshot contains a strange rendering of a titlebar in Windows Basic style (even though my machine runs the Aero theme):
I've noticed that some other apps also exhibit a similar behavior where they flicker on-screen but the titlebar artifact is not visible in the captured screenshot. Apps that do this include Office 2010, IE 10, and the Trillian tabbed chat window — in other words, windows that extend the non-client area seem to have this issue.
The code that reproduces this is simple:
void Screenshot(HWND hWnd) {
RECT rc;
GetClientRect(hWnd, &rc);
HDC hdcScreen = GetDC(NULL);
HDC hdc = CreateCompatibleDC(hdcScreen);
HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen,
rc.right - rc.left, rc.bottom - rc.top);
SelectObject(hdc, hbmp);
//Print to memory hdc
PrintWindow(hWnd, hdc, PW_CLIENTONLY);
}
Why am I seeing flickering and strange visual artifacts? What can I do to stop it?
For those, who have the same problem, do this:
const uint PW_RENDERFULLCONTENT = 0x00000002;
PrintWindow(hWnd, hDC, PW_RENDERFULLCONTENT);
If Aero is enabled, use BitBlt instead.
This comment in the chromium desktop capture source code was especially helpful:
// When desktop composition (Aero) is enabled each window is rendered to a
// private buffer allowing BitBlt() to get the window content even if the
// window is occluded. PrintWindow() is slower but lets rendering the window
// contents to an off-screen device context when Aero is not available.

Win32 Edit Controls of WS_EX_LAYERED parent dont receive mouse/click events when their background is transparent

I want to put some edit fields ontop of a splash screen which is rendered in another top level window (transparent PNG similar to this http://code.logos.com/blog/2008/09/displaying_a_splash_screen_with_c_part_ii.html) .
I made a secondary window which is always on top of my splash screen, and made it also transparent with WS_EX_LAYERED.
Now i set the background color of the edit fields in the wndproc by catching WM_CTLCOLOREDIT.
This works fine, my input controls are transparent (e.g. invisible) and only the entered text is visible on the splash screen.
Now the issue comes that the mouse cursor which indicates here is a text box does not work, neither can i click in that box to have it focus. The problem all disappears if i do NOT make the background of the edit control transparent. There is also no WM_NCHITTEST when its transparent. The only time im getting a mousecursor is if there is (visible)text already entered in the box
g_HWNControlsParent = CreateWindowEx( WS_EX_LAYERED,.....);
hwLoginField = CreateWindowEx(NULL,"EDIT", "-User-", WS_CHILD|WS_VISIBLE|WS_TABSTOP, ....g_HWNControlsParent);
SetLayeredWindowAttributes(g_HWNControlsParent,RGB(0, 0, 0), 0, LWA_COLORKEY) ;
in HWNControlsParent wndproc
case WM_CTLCOLOREDIT: { // BG Color of Input Fields
HDC hdc = (HDC)wParam;
SetTextColor(hdc, RGB(230,230,230));
SetBkColor(hdc, RGB(0,0,0)); // Color of Background where Text is entered
SetDCBrushColor(hdc, RGB(0,0,0)); // Color of Background where no Text is
return (LRESULT) GetStockObject(DC_BRUSH); // return a DC brush.
}
If you use an alpha of 1 instead of 0 for the transparent regions, they will still be transparent but will respond to mouse clicks.

Create or remove GDI shapes on command

I'm creating a win32 application. on the main window there are 5 buttons. in front of each button there is a small circle drawn. (using GDI tools. in case WM_PAINT). now when I press on a button the circle in front of it should colour in red colour. how can I do this.
If we create a edit box any time we can change the text on it using SendMessege to it. like that is it possible to change the colour on shapes drawn earlier.
Please can someone give me an advice.
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC;
HBRUSH brusha;
hDC=BeginPaint(hWnd,&ps);
brusha=CreateSolidBrush(RGB(0,255,0));
SelectObject(hDC,brusha);
Ellipse(hDC, 20, 20, 50, 50);
DeleteObject(brusha);
EndPaint(hWnd, &ps);
}
case WM_COMMAND:
switch(LOWORD(wParam))
{
case BUTTON:
{
//here I need to change the above drawn corcle to be red.
}
}
You can't change the color of an already drawn image, but you can redraw it. Use the Windows function InvalidateRect to tell the control that it needs to be redrawn, and you will get another call to your WM_PAINT handler. In the handler select the desired color before you draw your circle.

Drawing a system-like cursor, top-most, anywhere

I need to draw a system-like cursor that I simply can control the position of.
In other words, I need to draw a transparent image that looks just like the system cursor and I need it to be rendered on top of all other windows.
I've tried multiple approaches, but they all seem to have some downside.
I've figured out that I can load the cursor image by using LoadImage() and passing the resource OCR_NORMAL and casting it into a HBITMAP.
HICON NormalCursor = (HICON)LoadImage(NULL, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
Then getting the "desktop" HDC
hDC = GetDC(NULL);
Then I can try to draw it using DrawIconEx()
DrawIconEx(hDC, (int)x, 0, NormalCursor, 0, 0, NULL, NULL, DI_DEFAULTSIZE | DI_NORMAL);
The DI_NORMAL flag is supposed to combine the DI_IMAGE & DI_MASK flags giving me a transparent image/icon/cursor, but this is my result on the desktop:
Not to mention that if it moves it creates trails.
By making a transparent window using SetLayeredWindowAttributes like this:
SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 50, LWA_COLORKEY);
And having the background color of my window to be black, I can remove the background from the window. But due to doing alpha based on a color I get ugly black pixels around my cursor icon.
Can I make the background of a window transparent in some other way than using a color mask?
How do I draw a transparent cursor on top of all windows properly?
I would recommend that you do make your own window, and do something like what's described at http://www.codeproject.com/KB/GDI-plus/CsTranspTutorial3.aspx . It's in C#, but most of it is just win32 calls. It does a nice job of variable transparency, too, not just 0%/100%.
Isn't the outline of the cursor black? Is the problem just that you're making the outline transparent too? Why don't you just change the transparency color (and the background color of the window) to anything other than black or white?