|
I did a little test project:
HWND hwnd = ::CreateWindowEx(WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_NOACTIVATE,
AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS),
NULL,
WS_POPUP|WS_DLGFRAME,
0, 0, 100, 100,
NULL,
NULL,
GetModuleHandle(NULL),
NULL);
::SetLayeredWindowAttributes(hwnd, RGB(10, 20, 30), 255, LWA_COLORKEY);
::SetWindowPos(hwnd, CWnd::wndTopMost, 100, 100, 200, 50, SWP_SHOWWINDOW | SWP_NOACTIVATE);
it seems to be working for me, i get a topmost, layered window that does not grab the focus.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I got the problem with focus when I show the window on right click on the control in active dialog box. The window is anchored to some point inside the control and the window rect is less than the rect of the dialog box. If I do not set WS_EX_TOPMOST, the window is under the dialog box, and is not visible. If the ex style is set to WS_EX_TOPMOST, I have my problem. If the window is set outside the dialog box rectangle, it is wisible without WS_EX_TOPMOST. I think it is because the dialog stays as a topmost window.
What is interesting, if I would set this window as a modeless dialog box, there is no problem with flicker. I did not check the situation with focus yet.
I think Microsoft does some trick with the dialog box and its controls. When we are moving from contorol to control we see no flicker.
geoyar
|
|
|
|
|
I used a dialog based app to test what i wrote in my previous post, the window stayed above the dialog as it should, did you try the way i did? WS_EX_TOPMOST isn't specified when creating the window but SetWindowPos will make a topmost window. I'm not sure what you mean by flicker, when your new window gets the focus, it becomes the active window of your application, this will make your dialog repaint its border/caption to show it is no longer active, also the focus rect will be removed from whereever it was on the dialog. Then when you set the focus back, it will make your dialog the active window again, causing it to repaint its border and title again, along with the focus rect (if there is one), i guess that's what you mean, no? If you tab around the dialog's controls, this does not change the active window, thus, no border/title repaints.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Yes, you are right. It is about repainting the dialog border.
I tried SetWindowPos with SWP_NOACTIVATE|SWP_SHOWWINDOW and the first parameter as &wndTopMost and &wndTop. With &wndTop the window is invisible, with &wndTopMost it is visible. On both occasions the dialog window loses focus and the frame is repainted.
It happens no matter what the first parameter of the SetWindowPos you passed.
geoyar
|
|
|
|
|
How does your code look like now?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Sorry, I have deleted all SetWindowPos from my code.
I remember that in my other app I used a modeless dialog box with CStatic in it over the modal dialog box. I have no problem with focus, placement and visibilty of this box.
So I created a modeless dialog box CTipDlg m_tipDlg and added to OnRButtonClick:
OnRButtonDown(UINT nFlags, CPoint point)
{
m_tipDlg.Create(IDD_TIPDLG, this);
m_tipDlg.SetLayeredWindowAttributes(RGB(10, 10, 10), 0, LWA_COLORKEY);
m_tipDlg.ShowWindow(SW_SHOW);
.....................................................................
}
Now I see two dialogs, one modal, one modeless(layered, transparent and not topmost), with two active frames. The focus stays on control I have clicked.
It is the test of concept for now. It might not work for me at the end. But focus behaves as I wanted.
Of course it is overkill, because all I need is a visible window.
Of course I will look in CDialog MFC code.
Any help will greatly appreciated.
geoyar
|
|
|
|
|
I'd like to help, but i don't see how...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I coded a modeless dialog in and it works like the topmost window: the main dlg frame is changing. So I am again at square one.
geoyar
|
|
|
|
|
Finally, I did it.
It is about processing WM_NCACTIVATE in the main dialog.
Just like
BOOL CSliderGDIDlg::OnNcActivate(BOOL bActive)
{
if (bActive)
return CDialog::OnNcActivate(bActive);
return FALSE;
}
Of course the condition might and should be more sofisticated.
geoyar
|
|
|
|
|
All right, nice that it works, i don't see why this is better than the other solution but i don't see the whole picture so...congratulations.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
After a bit of trying and debugging this is what I got:
1. You are right: SetWindowPos with SWP_NOACTIVATE does not send WM_NCACTIVATE to other windows. So
SetWindowPos(&wndTopMost, x, y, cx, cy, SWP_SHOWWINDOW|SWP_NOACTIVATE);
does not change the main dialog/window frame. But control that have received mouse right click and created popup topmost window does lose focus. I had to restore focus manually, using SetFocus().
2. If the position and size of the window are not changing SetWindowPos will not redraw window if you do not call Invalidate() or InvalidateRect/Region() before call to SetWindowPos.
3. The window must be created without WS_VISIBLE. Other way even with WS_EX_NOACTIVALTE main dialog frame changes.
This is a code:
BOOL CTipWnd::CreateTipWnd()
{
BOOL bRes = FALSE;
bRes = CreateEx(WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST|WS_EX_NOACTIVATE,
AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS),
NULL,
WS_POPUP,
0, 0, 0, 0,
NULL,
NULL,
0); // Not visible
if (bRes)
{
CRect tipWndRect = SetTipWndRects();
bRes = SetLayeredWindowAttributes(bkgndCol.ToCOLORREF(), 0, LWA_COLORKEY);
SetWindowPos(&wndBottom, tipWndRect.left, tipWndRect.top, tipWndRect.Width(),
tipWndRect.Height(), SWP_NOACTIVATE); // Still not visible
}
return bRes;
}
void CTipWnd::UpdateTipWnd(..., bool bShow)
{
// Changing window layout
...........................
// Done. Now redraw and show it
if (bShow)
{
Invalidate(FALSE);
CRect tipR;
GetWindowRect(&tipR);
SetWindowPos(&wndTopMost, tipR.left,tipR.top, tipR.Width(), tipR.Height(),
SWP_SHOWWINDOW|SWP_NOACTIVATE);
}
}
And in calling control
void CSliderGdiCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
m_tipWndPtr = new CTipWnd;
m_tipWndPtr->SetOwner(this);
..............
BOOL bRes = m_tipWndPtr->CreateTipWnd();
if (!bRes)
{
delete m_tipWndPtr;
m_tipWndPtr = NULL;
}
else
{
UpdateTipWnd();
SetFocus();
}
}
..................
}
Thank you so much for your help.
geoyar
|
|
|
|
|
Yourwelcome.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I have MFC-based SDI GUI application.
Also I have a thread which contains custom messages queue. Each of these messages should be posted to GUI, most of them adds new items to ListView.
If I'm just doing PostMessage( WM_MY_CUSTOM_MESSAGE ) to main GUI thread I have 2 undesirable effects:
1. Main thread queue is overflowed and I have message-leaking;
2. GUI becomes unresponsible - windows aren't repainted, I can't push toolbar and dialog buttons and so on;
Question:
How can I organize posting messages to GUI from the secondary thread and avoid 2 above effects (especially the second one)?
|
|
|
|
|
In your app where the message is handled, you can try to SetRedraw(FALSE) when processing the first message and then SetRedraw(TRUE) when all messages are received. You'll likely need to add a complete indicator with the message to accomplish this.
Chris Meech
I am Canadian. [heard in a local bar]
In theory there is no difference between theory and practice. In practice there is. [Yogi Berra]
|
|
|
|
|
Is there a tool available to process source code to detect mismatches between the sprintf format string and the arguments that follow? For example specifying a %s and neglecting to provide a c string to satisfy it, etc.
I use hundreds of sprintf's to format log messages and am looking for a way to insure correctness without eyeballing each and everyone of them.
When this happens during runtime in my code the program thread seems to hang and when it's the main server thread the other secondary threads cease to get serviced and as they are designed to timeout, they do, and a programmatic exit occurs.
|
|
|
|
|
If you're using C++ don't fart about with sprintf, use std::stringstream - you'll avoid problems of lobbing the wrong thing at a particular format specifier.
If you're stuck using C then there's not a lot I can suggest although PC-Lint is pretty good at finding errors in the printf family of functions.
Cheers,
Ash
|
|
|
|
|
Alan Kurlansky wrote: detect mismatches between the sprintf format string and the arguments that follow?
Yes, there are a couple of tools available. Have a look at the following:
Happy debugging!
M
PS: This post is for developers who prefer format() over STL string streams.
PPS: And if you are one of them, you could have a look at Boost Format library.
|
|
|
|
|
I have a C++ dll, lib and the corresponding header file. I would like to create a dummy wrapper dll that simply returns True from some of the functions in the dll, so that when testing, I can replace the dll with the test one and have the application still work without recompilation.
Some function however (error handling) I would like to keep. My approach is as follows.
1. Copy the .h file in my local project folder and remove the extern keyword for the functions I would like to override, than add implementation for those functions.
2. All functions are declared __declspec( dllexport ) so that they are included in the dll.
3. I include the original lib file as an Additional dependency in the project, so I can link to the function definitions for the functions I'm not overriding. The project is set to DLL (I'm using VS)
Everything compiles fine, but when I use depends to look at the dll, I only see the functions I've implemented, not the ones from the lib.
Any ideas?
|
|
|
|
|
So you expect the dll to automagically implement the functions you didn't write? If you find a compiler to do that let me know (private email please, I don't want everyone else to know).
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
|
|
|
|
|
You really have a fantastic signature! Great!
|
|
|
|
|
I expect to link to the static lib file and export those implementations. Or are those just stub functions that load the dll code?
|
|
|
|
|
Ah ha, just seen one point of confusion you've got...
When you produce a DLL you can produce something called an import library. This is nothing like an ordinary static library (although you can add object files to it if you want) but essentially just a lump of data describing the functions exported from the DLL - essentially just the function's names and position in the exported function table. They don't contain any code.
So if you link with a DLLs import library then all that means is that the corresponding DLL will be automatically loaded when the program starts and the loader can fixup the addresses of the imported functions.
Cheers,
Ash
|
|
|
|
|
Yeah I realized that after a while
|
|
|
|
|
I wouldn't try using library interpositioning for this sort of thing. While you can implement a DLL that calls selectively forwards functions to another DLL it ends up being a bit of a headache [1]. The approach I tend to use is...
- wrap the DLL in a class
- extract an interface class out of the class you've implemented (all the functions are pure virtual)
- implement the interface again, passing the bits you want through to the DLL and reimplementing the bits you don't want to
- select at runtime or compile time (depending on the type of testing you want to do) which implementation of the interface you want to use
This method is something to consider with any third party library so when it doesn't work properly you've got a central point to either replace it or patch its functionality.
Cheers,
Ash
[1] If you really want to do use library interpositioning then...
- reimplement the entire interface of the wrapped DLL, starting off by just returning succeeded, true, whatever is appropriate
- reimplement the functions you want to pass through by (a) manually loading the wrapped DLL and (b) calling the wrapped function
- reimplement the bits you don't want to pass through however you want
This saves the balls ache of link order of the wrapping and wrapped libraries.
|
|
|
|
|
So I can't simply use the external function definitions to expose those functions in the dll and statically link the lib file to the dll for the actual implementation??
Wrapping the dll in a class sounds like an overkill, I wanted something quick and dirty. If I try to use the library interpositioning you described at the bottom of your post, won't the functions I import from the wrapped dll clash with the functions I defined in the wrapper, being the same name and signature??
|
|
|
|
|