(this is not MFC)
I created a window which is transparent and covers the whole screen. However, I want it to be merely an overlay, not accepting any clicks or keyboard presses anywhere, only covering parts of the screen (and even there, don't accept input). It should be always on top (works so far) and should not block input to the windows below it. Is there a way to set this somewhere or a way to workaround this?
EnableWindow(hWnd, false); does not do what I want (obviously).
Ah, sorry for posting. Finally found it out!
WS_EX_TRANSPARENT is the style you want to add.
Related
I'm asking this question ahead of time, since I haven't gotten around to attempting an actual, real implementation yet. Win32 (C++) is turning out to be a colossal pain to program. But, my question is this:
I want to make my application's window become fully transparent with a dotted perimeter when resizing the window. How would I accomplish this? Think of what happens in Windows 3/3.1 (I believe it was this version) when resizing a window. Everything goes transparent, with a dotted-outline where the mouse is moving, then it repaints the entire contents. That's what I'm trying to achieve.
A while ago, I tried handling the WM_(ENTER/EXIT)SIZEMOVE messages and make use of SetWindowLong() to set the WS_EX_TRANSPARENT extended style, but my window became (indefinitely) pass-through, and when the window's focus was killed, it could never again regain focus.
Do I need to handle other messages like WM_NCLBUTTON(DOWN/UP)? I have a boolean flag to tell me when to halt drawing during resizing, and the logic for determining when I'm resizing works perfectly, but I cannot get the visuals to work. I'm not sure which parts of the Win32 API to actually use. I've done some research, and uxtheme.lib/.h seems promising, but I'm not sure how that would work with WM_NCPAINT, which I have been using with (some) luck.
EDIT
I need to clarify something, in case anyone was confused or unsure of what I meant. What I meant by the Windows 3.1/3 resizing scenario is that once WM_ENTERSIZEMOVE has occurred, the window (controls, caption, frame) should be made entirely invisible, and the window's nonclient-region's perimeter should display a dotted-outline of sorts. Then, only until the resize has been finished, when WM_EXITSIZEMOVE has occurred should the entire window (controls, caption, frame) be fully redrawn, updated, and returned to its normal, functional state. Sorry for any miscommunication!
I found the answer... After so long, finally found it. Here's where I found it! http://www.catch22.net/tuts/win32/docking-toolbars-part-2# - Hope it helps anyone else possibly in my shoes!
And it turns out that the solution was rather simple. In fact, the core concept of what is explained is near-completely what I was thinking, yet I just had no idea how to implement it. The solution involves overriding the default WM_NCLBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP (specifically when initiating a window movement) messages, and drawing a patterned rectangle which follows the position of the cursor. Then, afterwards, calling SetWindowPos or some other similar function to relocate the window.
Basically, block Windows from attempting to display anything graphics related until the resizing has been finished. Then, and only then, make Windows move the entire window in one huge, foul swoop.
Based on Remy's comment, there is a global option and corresponding registry setting for this, so perhaps try setting the registry setting when the move starts and restoring it when the move finishes.
Unfortunately this doesn't work as Windows appears only to pick up the setting on restart, broadcasting WM_SETTINGCHANGE also doesn't trigger it, which is a pity as doing something yourself that the OS already has an implementation of do is rather a poor state of affairs.
I'm using CDateTimeCtrl in my dialog application. Now we have already agreed with the client about the size of the CDateTimeCtrl. The 1st problem is, it is by default left-aligned, and is really close to the left border. The 2nd problem is it leaves a really wide space on the right side of the control. Hence, the solution to solve both problems would be to center align text.
Unfortunately, in the Properties window, there is no alignment property (except for "Right align" in which there were no changes when I tried to toggle it).
Now, I've tried calling CWnd::ModifyStyle in the OnInitDialog() event. Also, no luck with this.
For the actual code,
auto timePicker = (CDateTimeCtrl*)GetDlgItem(IDC_TIME_PICKER);
timePicker->ModifyStyle(0, SS_CENTER);
return TRUE; // this function is the OnInitDialog()
What could I be missing that calling this function does not center the text of CDateTimeCtrl?
You can't use a style that is suited for a static control and use the style in a date time control.
All available styles are listed here.
The control itself also doesn't have child controls. It draw the values itself.
Maybe there is a chance to subclass the control and overwrite the WM_PAINT message and doing a kind of ownerdrawing by yourself.
I don't use the date time picker and I confess: I don't like it at all. I wrote a complete own control that is much more flexible.
I need a GroupBox control for something else that showing it in application's window. That's why I want to disable the frame surrounding it (or at least make it invisible by, for example, drawing it with the color that matches with window's background). Both are harder than I thought though, I've been loking for the solution everywhere and found nothing. I don't want to use anything as straightforward as painting over it in WM_PAINT-case in window procedure because there will be that annoying sparkling when I move the window.
I'm running out of ideas, tried a few things on my own, none worked. Anyone have some tips?
I'm currently using Google Chrome as my main browser. I wondered how the developers put the custom titlebar, because I wanted to incorporate into one of my own applications.
If you guys don't know what I'm talking about, here's a picture:
I found an article about the interface, which is here:http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/33870516-9868-48d3-ab53-6269d9979598
However, I don't know how to do this. I'm currently using VC++ Express. Can anyone give me step by step instructions and how to get an interface like that? Except I don't want tabs on top.
I'm writing this in Win32.
If memory serves, the main things you need to handle aren't WM_NCCALCSIZE, but WM_NCHITTEST and WM_NCPAINT.
WM_NCHITTEST is what tells the system when the cursor is over the title bar, so you need to take a cursor position and decide whether it's over the area you consider "title bar". In particular, if the user clicks and drags with the cursor in this area, the whole window gets dragged.
WM_NCPAINT is just like WM_PAINT except for the non-client area -- i.e., this is when you need to actually draw whatever you're going to for the title bar (and window borders, if memory serves).
I should add that I haven't played with this in quite a while. There's almost certainly more I'm not remembering right now.
OK, the answer is simple:
Chomre simply does not use the Windows built in functionality for drawing a frame border, titlebar, titlebar buttons, etc..
When you call GetWindowRect(hChromeWindow) and GetClientRect(hChromeWindow) you will notice that the rectangles are identical. This means that Chrome turns off all Windows functionality for drawing a border (simply return 0 in WM_NCCALSIZE without doing anything else) and then they draw EVERYTHING into the client area.
So in WM_PAINT they draw the titlebar and the upper part of the window (URL bar, tabs, etc..) together. In WM_NCPAINT they do nothing.
This is not the common way to do it, but the easiest, and it is bullet-proof.
By the way: Java applications do the same.
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.