Cannot implement meter in windows API - c++

I am using the windows API (in C++) to create a windows application.
Now, I have a progress bar which I want to show like a meter. A meter is blue and has no animation. I cannot figure out how to implement this, and if I have to, I will just settle for the usual green progress bar.
Please help.
EDIT: At least, is it possible to disable the animation (highlight the slides across the filled section of the bar)?
EDIT2:
Here is the C++ solution if anyone else is having this problem:
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hwnd,&ps);
RECT r;
HTHEME theme = OpenThemeData(hwnd,L"PROGRESS");
SetRect(&r,10,10,100,25);
DrawThemeBackground(theme,hDC,11,2,&r,NULL);
SetRect(&r,10,10,50,25);
DrawThemeBackground(theme,hDC,5,4,&r,NULL);
CloseThemeData(theme);
EndPaint(hwnd,&ps);

You can draw this style of progress bar with DrawThemeBackground(). You'll find the theme name, part and state numbers in my answer in this thread.

The built in control cannot do this... however, it's not like ProgressBar is a complicated control. If you want nothing but a blue rectangle, use DrawRect and draw a blue rectangle.

Related

Win32 DrawText stange aligment issue

Using Win7 x64 c++ with MSVC2010 pro.
I have noticed a really strange bug when using the Win32 DrawText to draw some text for a custom control. Its a pretty standard thing to do I'm sure. I did see a post about something similar and the solution was to use one the TextOut calls, but that doesn't resolve my issue.
I've subclass the "Static" control using the SetWindowSubClass and I'm hanlding the wm_paint message as:
case WM_PAINT:
{
RECT rect;
PAINTSTRUCT ps;
HDC hdc = BeginPain(hWnd,&ps);
// Create a back buffer to draw to
HDC hdcBack = CreateCompatibleDC(hdc);
GetClientRect(hWnd,&rect);
HBITMAP hbmBackbuffer= CreateCompatibleBitmap(hdc,rect.right,rect.bottom);
size_t iLength = 0;
StringCchLength(LCDText,240,&Length);
SelectObject(hdcBack,hbmBackbuffer);
// Draw a black background to clear previous text
SelectObject(hdcBack,GetSysColour(1)); // Black
Rectangle(hdcBack,rect.left,rect.top,rect.right,rect.bottom);
// Set the font, tranparency and text colour
SelectObject(hdcBack,LCDFont);
SetBkMode(hdcBack,TRANSPARENT);
SetTextColor(hdcBack,0x0000ff00);
DrawText(hdcBack,LCDText,(int)iLength,&rect,DT_LEFT);
// display
BitBlt(hdc,0,0,rect.right,rect.bottom,hdcBack,0,0,SRCCOPY);
// cleanup
DeleteObject(hbmBackbuffer);
DeleteDC(hdcBack);
EndPaint(hWnd,&ps);
break;
}
This actually works very well. The problem is that the the 'label' can display 3 lines of 40 chararcters, and after the 27 character of each line the next chars to the end of that line are 1 or 2 pixels higher up the screen. It's not immediately apparent but once you notice it then it kindof draws your attention.
Does anyone have any ideas or experience with this?
ps - I typed the code in manually into the forum so there may be some silly typos but the real code does work properly apart the alignment issue.
Regards
Dave.

Is there any way to fix the side effect of "DwmEnableBlurBehindWindow" in VC6.0?

I have met an exactly problem which metioned in the MSDN Topic:DWM Blur Behind Overview.
After DwmEnableBlurBehindWindow was called, the client area became a beautiful glass, but unfortunatly, all of black text on the controls(BUTTONs,EDITs,STATICs etc) became transparent too, just like that Topic on MSDN.
Any way to fix this?
By the way, My develop env is VC++ 6.0, and I have to draw some glowing text with DrawThemeTextEx API, so I can't use DwmExtendFrameIntoClientArea simplely. I MUST use DwmEnableBlurBehindWindow to enable the glass effect of client region.
Thanks a lot!
2012/6/19
Update:
By changing the TRANSPARENT KEY COLOR of a window to a non-black color with "SetLayeredWindowAttributes", then using "DwmExtendFrameIntoClientArea" can solve the caption text problem of CONTROLS(BUTTONs,EDITs etc) on the glass window.
But in this way, "DrawThemeTextEx" could not work properly. It looks like that DrawThemeTextEx could only use the RGB(0,0,0) as its TRANSPARENT KEY COLOR.
So, is there any API could change the TRANSPARENT KEY COLOR which used by "DrawThemeTextEx" within ?
My ultimate goal is to draw some glowing text on a glass(Aero) window without the "DwmEnableBlurBehindWindow" side effects which metioned in the MSDN Topic:DWM Blur Behind Overview,http://msdn.microsoft.com/en-us/library/aa969537.aspx.
And if there is another way to do it, I'm very glad to hear :)
And thanks a lot, again! :)
Take a look at Painting the caption title in MSDN:
Find the line HBITMAP hbmOld = (HBITMAP)SelectObject(hdcPaint, hbm); in the example.
Then, add this line after it:
// You should have set RGB(200,201,202) as the transparency key
FillRect(hdcPaint,&rcClient,CreateSolidBrush(RGB(200,201,202)));
Although the effect does not seem to be perfect, it solves the problem.
Reference: C++ WinAPI Conflict between SetLayeredWindowAttributes and BitBlt

Plotting a graph in C++ window

I want to plot a graph out of simple functions/set of coordinates in a window. I know the c++ win32 basics and I can make a simple window with buttons and other control objects. But which is the fastest and easiest library to plot a graph to my program?
I expect you are using Win32 API (not CLR).
Theory is easy, you need to obain device context withing WM_PAINT message.
You can use main window or any child window (control - static, button) inside main window.
Here are some usefull links:
http://www.codeproject.com/Articles/2078/Guide-to-WIN32-Paint-for-Intermediates
http://www.codeproject.com/Articles/66250/BeginPaint-EndPaint-or-GetDC-ReleaseDC.aspx
eg:
case WM_PAINT:
BeginPaint(hWnd, &ps);
LineTo(ps.hDC, 30,30);
EndPaint(hWnd, &ps);
return 0;
This will draw line from 0,0 to 30,30
Here is the light, easy to use library:
http://www.codeproject.com/Articles/1546/Plot-Graphic-Library

most simple type of graphic application in visual studio

Whats the most simple way (without much fancy stuff and no big setup overhead) to create a c++ project with visual studio where i can create some graphical debug output? (mainly drawing some lines, circles and triangles in a window. doesn't have to be performant or look pretty)
thanks!
The quickest way: create a new project, find or create the paint message handler (in Win32 it'll be in WndProc under "case WM_PAINT:", and in a WinForms (.net) project you'll override OnPaint), and add code to draw some stuff.
Well, for this I'll assume you would want to just use Gdi.
In a windows app, process the WM_PAINT message.
Here is an example that draws a rectangle:
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd,&ps);
Rectangle(hDC,10,10,30,30);
EndPaint(hwnd,&ps);
}

Drawing issues with c++

I'm sort of new to c++ and i'm trying to create a game.
I have a 2d array RECT_GRID of rectangles.
I have a 2d array GRID of unsigned short.
I fill the rectangle array during WM_CREATE
The WM_PAINT event paints rectangles for all the elements in the array. The color of the rectangle is based on the value of GRID[x][y]
I made it so when the down key is pressed, It changes the color of one of the rectangles by setting GRID[1][XMOVE] = to a different color
then it invalidates the client rectangle
Basically what happens is, it works well for a while, but eventually it just stops drawing stuff. I checked my XMOVE variable during debug, I checked by grid values and stuff and everything is fine. When I remove the for loop from the paint event and focus on 1 specific rectangle, it never fails, but if I try to redraw all of them at once, after about 20 times, it stops painting things. What could cause this? I'm new to c++ and I bet I'm not painting properly and causing an overflow or something.
If anyone could explain what's going wrong, or a proper way to do this, I'd really appreciate it. I could not find anything like this example on Google.
Thanks
EDIT:
I'm using 3 global brushes
HBRUSH A;
HBRUSH B;
HBRUSH C;
and when I modify them, I always say A = MakeBrush(NUM);
ami I using brushes properly?
My first guess, if you're a total GDI/C++ newbie, is that you are probably creating a lot of Pens and Brushes. These are constrained resources in Windows. You can only create so many of them before you start to tax your resources. So either make your Brushes and Pens and Windows, etc all at once and re-use them, or dispose of them properly when you're done. I recommend getting a copy of "the Bible" (http://www.amazon.com/Programming-Windows%C2%AE-Fifth-Microsoft/dp/157231995X/ref=sr_1_1?ie=UTF8&s=books&qid=1252788457&sr=8-1) and reading the chapters in there about drawing.
EDIT: It doesn't sound like you're modifying your brushes properly, but since I can't see the code for MakeBrush, I don't know. You're probably creating a lot of brushes behind the scenes and you don't even know it. Seriously, get a copy of Petzold's book and spend an hour or two. You'll end up with more hair on your head later! ;-)
You'll notice in all GDI examples, a 'CreatePen' or 'CreateSolidBrush' will be followed by a delete object. This is because they are limited resources in windows, and you can run out of them if you don't delete them when you're finished.
PAINTSTRUCT Ps;
HDC hDC = BeginPaint(hWnd, &Ps);
HBRUSH NewBrush = CreateSolidBrush(RGB(250, 25, 5));
SelectObject(hDC, NewBrush);
Rectangle(hDC, 20, 20, 250, 125);
DeleteObject(NewBrush);
EndPaint(hWnd, &Ps);
If you forget to include the 'DeleteObject' call, then you will have problems after you use up all the brushes available. It's actually fun to try =)