Date: | October 9, 2003 / year-entry #91 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20031009-00/?p=42213 |
Comments: | 13 |
Summary: | Bitmap brushes used to be these little 8×8 monochrome patterns that you could use for hatching and maybe little houndstooth patterns if you were really crazy. But you can do better. CreatePatternBrush lets you pass in any old bitmap - even a huge one, and it will create a brush from it. The bitmap will... |
Bitmap brushes used to be these little 8x8 monochrome patterns that you could use for hatching and maybe little houndstooth patterns if you were really crazy. But you can do better. CreatePatternBrush lets you pass in any old bitmap - even a huge one, and it will create a brush from it. The bitmap will automatically be tiled, so this is a quick way to get bitmap tiling. Let GDI do all the math for you!
This is particularly handy when you're stuck with a mechanism where you are forced
to pass an For example, let's take our scratch program and give it a custom tiled background by using a pattern brush. HBRUSH CreatePatternBrushFromFile(LPCTSTR pszFile) { HBRUSH hbr = NULL; HBITMAP hbm = (HBITMAP)LoadImage(g_hinst, pszFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); if (hbm) { hbr = CreatePatternBrush(hbm); DeleteObject(hbm); } return hbr; } BOOL InitApp(LPSTR lpCmdLine) { BOOL fSuccess = FALSE; HBRUSH hbr = CreatePatternBrushFromFile(lpCmdLine); if (hbr) { WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = g_hinst; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = hbr; wc.lpszMenuName = NULL; wc.lpszClassName = CLASSNAME; fSuccess = RegisterClass(&wc); // Do not delete the brush - the class owns it now } return fSuccess; }
With a corresponding adjustment to if (!InitApp(lpCmdLine)) return 0; Pass the path to a *.bmp file on the command line, and bingo, the window will tile its background with that bitmap. Notice that we did not have to change anything other than the class registration. No muss, no fuss, no bother. Here's another way you can use bitmap brushes to save yourself a lot of work. Start with a new scratch program and change it as follows: HBRUSH g_hbr; // the pattern brush we created HBRUSH CreatePatternBrushFromFile(LPCTSTR pszFile) { ... same as above ... } void PaintContent(HWND hwnd, PAINTSTRUCT *pps) { BeginPath(pps->hdc); Ellipse(pps->hdc, 0, 0, 200, 100); EndPath(pps->hdc); HBRUSH hbrOld = SelectBrush(pps->hdc, g_hbr); FillPath(pps->hdc); SelectBrush(pps->hdc, hbrOld); }
And add the following code to WinMain before the call to g_hbr = CreatePatternBrushFromFile(lpCmdLine); if (!g_hbr) return 0; This time, since we are managing the brush ourselves we need to remember to DeleteObject(g_hbr); at the end of WinMain before it returns. This program draws an ellipse filled with your bitmap. The |
Comments (13)
Comments are closed. |
Nice. But if I remember correctly, it was not supported on Win95.
BTW: can you explain why PaintDesktop fails with memory device context on 2k/XP?
Neat, but I’m intrigued – what prompted you to post about this? Any particular example you had in mind?
You can’t PaintDesktop into a memory DC because PaintDesktop does an EnumDisplayMonitors to render the desktop on each monitor, but a memory DC doesn’t have any monitors.
There was nothing in particular to inspire this topic. Sometimes I’ll just write about something I think doesn’t get written about enough.
I’m programming a GINA, and debugging using the checked version of Winlogon. Look this err message:
RTL: RtlNtStatusToDosError(0x52e): No Valid Win32 Error Mapping
RTL: Edit ntosrtlgenerr.c to correct the problem
RTL: ERROR_MR_MID_NOT_FOUND is being returned
156.88> Winlogon-Trace-SAS: LOGONNOTIFY message 9
Can you send the file, so I can correct the problem??? LOL :)
Yesterday my VS.NET asked me for some .c file from NT kernel. I told him I don’t have, and he said: "ok, take this assembly code instead". :-)
I have two questions for Raymond but couldn’t find a way to email him directly. Why has fast alt tab switching in Windows not been working exactly as it should since I can remember. I am a web developer so usually have several apps open when developing. It seems the algorithm for what you last used when alt-tab switching sometimes puts the last app you used at the bottom of the stack, so you have to tab through the 14 other windows just to get to the one you used immediately previous to switching. And to top it off, this action seems intermittent. Sometimes it works great, other times it works as I described. Have you come across this bizarre behaviour at all?
Also the other thing I wanted to ask about is when you right click on an item in the task bar, you get a pop-up menu with the Close (Alt F4) option listed at the bottom. Standard fair in Windows…right.
I got into a habit of closing down windows by right clicking then selecting the bottom option. Which works great except for those apps that don’t have Close as the bottom option in the right click menu – they have something else instead. Examples are any HTML Help app, which have “About HTML Help”, and MS Windows own Help window, which has "Go To" as the bottom option…(yeah that’s intuitive).
I was wondering if you could shed any light on these two idiosyncrasies?
Anthony-I haven’t any explanation, just this note: Alt-shift-tab iterates the coolswitch list backwards if that happens to you (ie your app moves to the end of the list).
Anthony – about tastk switching
the app moves to the bottom of the stack when minimized. If you just use alt-tab it will be the next.
Also, for the taskbar context menu, it mirrors the system menu — the menu you get when you click on the application icon of a window. Applications are free to modify this menu as they wish (more or less). Some applications choose to put additional items on this menu.
2Anthony
You can hold Ctrl key while selecting items in task bar. Then right click and you’ll get "common denominator" menu for them. So, you’ll be able to close (minimize, etc.) all of them at once.
"Sometimes I’ll just write about something I think doesn’t get written about enough."
Hehe. Any chance you take suggestions for stuff that "doesn’t get written about enough"?
Alex: thanks for that tip – very nice feature :)
If you want to suggest a topic, add a comment or email me. (Note that I get approximately a thousand of pieces of email a week, and that’s not counting the spam, so please don’t be hurt if I don’t personally acknowledge your message. I did get it and I did read it.) Note that I often decide not to comment on a topic because I don’t feel qualified to discuss it, or discussing it would reveal proprietary information, or because I don’t think the topic is of general interest. Again, please don’t be offended if this happens to your topic.
Commenting on this article has been closed.