change WindowClass to full screen - c++

so am trying to make my window class full screen, but it's not working , it just flickers black then it does not become full screen here is the source code :-
void InitEngine::Init(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd, DesktopScreenInfo * ScreenInfo, LPSTR WindowName)
{
mWindoClass = new WNDCLASSEX();
ZeroMemory(mWindoClass,sizeof(WNDCLASSEX));
if(ScreenInfo) mScreenInfo = ScreenInfo;
else mScreenInfo = &DesktopScreen::GetScreenInfo();
mWindoClass->cbSize = sizeof(WNDCLASSEX);// window size
mWindoClass->style = CS_HREDRAW | CS_VREDRAW; // so it draw when Horizontal or Vertical change
mWindoClass->lpfnWndProc = WindowProc;
mWindoClass->hInstance = hInstance;
mWindoClass->hCursor = LoadCursor(NULL, IDC_ARROW); //load normal cursor
mWindoClass->hbrBackground = (HBRUSH)COLOR_WINDOW;
mWindoClass->lpszClassName = "PoPEngineClass";
DEVMODE screen;
memset(&screen,0,sizeof(screen));
screen.dmSize = sizeof(screen);
screen.dmPelsWidth = mScreenInfo->Width;
screen.dmPelsHeight = mScreenInfo->Height;
screen.dmBitsPerPel = mScreenInfo->ScreenDepth;
screen.dmDisplayFrequency = mScreenInfo->FrameRate;
screen.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
ChangeDisplaySettings(&screen, CDS_FULLSCREEN);
RegisterClassEx(mWindoClass);
WindowHandel = CreateWindowEx(NULL , mWindoClass->lpszClassName , WindowName , WS_POPUP, 0 , 0, mScreenInfo->Width, mScreenInfo->Height, NULL, NULL, hInstance, NULL);
ShowWindow(WindowHandel, nShowCmd);
UpdateWindow(WindowHandel);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

ChangeDisplaySettings does not actually make a window full-screen - despite the perhaps misleading name of the flag. To make a window go full screen, you basically have to do a bunch of work yourself:
remember the old position
change the window style to remove the borders and titlebar
get the screen size, set the window's new position to cover the screen
and put it on top of other windows (the latter two you can do with the SetWindowPos call.)
There's a couple of answers to this same question elsewhere on SO -- but there's problems with them. Instead recommend reading Raymond Chen's blog entry on this: How do I cover the taskbar with a fullscreen window? - the difference between what he's doing any my list above is that he's creating a new window without vs modifying an existing one; which is actually a neater approach as it means you don't need to deal with remembering/restoring the old position.
ChangedisplaySetting's CDS_FULLSCREEN flag has a different meaning: the call is for changing display mode settings, not making a window fullscreen; but the flag is telling windows that the mode change is temporary, so should't be saved. For example, if an app that plays back video at a specific resolution is going full screen, it might want to change the actual screen resolution to match the video, but just so long as it is full screen. Or a OpenGL game or similar might use this to ensure it is running full-screen with a specific resolution. So it really means "change the display settings to these, but I'm doing this just because I'm going fullscreen, so don't make the change permanent'. Raymond Chan writes a bit more about this flag on his blog here. If you don't care about the screen resolution settings, and you just want your window taking up all of the screen area, then you don't need this call.

Related

Background combobox on gradient parent window?

I have window with gradient background. Combobox have own background brush.
How can I remove white corner in combobox? How can I change brush or another way.
On picture white corner marked by red frame.
I create combobox as:
DWORD dwStyle = WS_CHILD | CBS_DROPDOWNLIST;
if (m_bVisible) dwStyle |= WS_VISIBLE;
m_hWnd = CreateWindow(WC_COMBOBOX, NULL, dwStyle,
m_posX, m_posY, m_width, m_height, m_hParent, (HMENU)m_id, m_hInstance, NULL);
I tried changing background brush with message WM_CTLCOLOREDIT, but no effect:
case WM_CTLCOLOREDIT:
if ((HWND)lParam == m_hSrcListBox)
{
return (LRESULT)m_hBrush;
}
break;
=== SOLVED. WORK VERSION ===
First way.
In parent WndProc:
case WM_CTLCOLORSTATIC:
if ((HWND)lParam == m_hSrcListBox)
{
return (LRESULT)m_pSrcListBox->GetHbrush();
}
break;
In my class:
//
// CListBox::GetHbrush().
//
// Get brush.
//
HBRUSH CListBox::GetHbrush()
{
if (!m_hBrush)
{
m_hBrush = CreateTransparentBackgroundBrush(m_hParent, m_hWnd);
}
return m_hBrush;
}
Create transparent background:
//
// CListBox::CreateTransparentBackgroundBrush().
//
// Create transparent background for element.
//
HBRUSH CListBox::CreateTransparentBackgroundBrush(HWND parent, HWND client)
{
RECT rct;
POINT p1;
POINT p2;
GetWindowRect(client, &rct);
p1.x = rct.left;
p1.y = rct.top;
ScreenToClient(parent, &p1);
p2.x = rct.right;
p2.y = rct.bottom;
ScreenToClient(parent, &p2);
HDC hdcParent = GetDC(parent);
HDC hdcClient = GetDC(client);
HDC hdcmem = CreateCompatibleDC(hdcClient);
HBITMAP hbitmap = CreateCompatibleBitmap(hdcClient, p2.x - p1.x, p2.y - p1.y);
SelectObject(hdcmem, hbitmap);
BitBlt(hdcmem, 0, 0, p2.x - p1.x, p2.y - p1.y, hdcParent, p1.x, p1.y, SRCCOPY);
HBRUSH pattern = CreatePatternBrush(hbitmap);
DeleteDC(hdcmem);
DeleteObject(hbitmap);
ReleaseDC(client, hdcClient);
ReleaseDC(parent, hdcParent);
return pattern;
}
Second way.
In parent WndProc draw background in WM_ERASEBKGND message, then the corners will not.
case WM_ERASEBKGND:
m_hdc = (HDC)wParam;
// draw background.
return TRUE;
break;
The result of both methods:
For dialog boxes, handle WM_CTLCOLORDLG and return a background brush for the combobox
If you are displaying this combobox in a dialog, the trick is actually to handle the WM_CTLCOLORDLG message in your dialog's window procedure. In response to this message, you return a handle to a brush that the dialog box will use to paint its background.
case WM_CTLCOLORDLG:
{
// NOTE: This code is wrong because it creates a new brush object each time it processes
// the message, which it promptly leaks. It is merely for demonstration purposes.
// Normally, you would create the brush once, in response to WM_INITDIALOG,
// cache it away, and return that same cached handle each time, finally destroying
// the brush in response to WM_NCDESTROY.
HBRUSH hBrush = CreateSolidBrush(RGB(255, 120, 0));
return reinterpret_cast<INT_PTR>(hBrush);
}
                    
This is the standard, documented way of changing the background color of a dialog box, and it also solves the problem with the combobox. Apparently, for whatever reason, combobox controls also use this brush to paint their background. I suppose they send a WM_CTLCOLORDLG message to their parent when they are painting themselves.
Of course, this limits you to the graphics capabilities of a GDI brush. You can draw any system or solid color that you want, or even use a hatch or pattern/bitmap brush, but there is no simple way of creating a gradient brush. (GDI+ has one, but not GDI.) Normally it wouldn't matter—you'd just call the GradientFill function in your WM_PAINT (or even WM_ERASEBKGND) message handler. That works fine for the dialog's background, but the combobox still draws its background with the brush returned by WM_CTLCOLORDLG, so it still has those 4 dots on its corners drawn in COLOR_3DFACE (which is the brush that the default dialog procedure returns).
                    
Returning a null brush (NULL_BRUSH/HOLLOW_BRUSH) from WM_CTLCOLORDLG doesn't work, either. It changes the appearance slightly, such that the upper-right and lower-left corner pixels are now filled with something that looks like COLOR_3DSKSHADOW, but they are still visibly filled with a color other than the actual background gradient.
                    
So if you really want it to look nice, you are left with only a single option: returning a handle to a GDI brush. And of course, it needs to be the same brush as is used to draw the dialog's background.
If you want a gradient fill, the only solution I can think of is using a pattern/bitmap brush, where the bitmap (DDB or DIB) is your gradient. Not great, but at least the days of Windows 9x limiting us to 8×8 patterns are long gone. Maybe someone more inventive than me can use this information to think of a better workaround?
For other windows, handle WM_CTLCOLORSTATIC and return a background brush for the combobox
All of that for a dialog box. But what about if you are displaying the combobox in a standard window (i.e., something other than a dialog box)? The WM_CTLCOLORDLG message is never sent in this case.
Instead, the combobox sends a WM_CTLCOLORSTATIC message to its parent window, and then uses the brush handle returned in response to that message to paint its background.
This is weird, I know. I only stumbled across it by conducting empirical tests, and I'm not sure quite sure what the rationale was. If I had to guess, I'd say that the CBS_DROPDOWNLIST style makes the combobox non-editable (i.e., it's not a true combobox because there is no Edit control), so instead of WM_CTLCOLOREDIT, it uses WM_CTLCOLORSTATIC. A disabled Edit box sends WM_CTLCOLORSTATIC, too, and so does a disabled combobox with the "normal" CBS_SIMPLE and CBS_DROPDOWN styles.
Weirder still, this only happens when the Aero theme is enabled (Vista and 7). It doesn't happen on Windows 10, or with the Luna theme (Visual Styles under XP), or with the Classic theme. (I didn't test on Windows 8 or 8.1.) Not that it matters, I suppose, since all of those other themes draw a simple rectangular combobox, leaving no corner pixels for the background to show through.
Whatever the logic, the solution remains to handle the WM_CTLCOLORSTATIC message and return the brush you wish the combobox to use to paint its background.
The same considerations apply here as those discussed above for the dialog box. If your window uses a solid-color background or a system color, you are home-free. Simply return a handle to the same brush that you set as the window class's background brush. If you want to use a gradient, you'll need to figure out a way to represent that gradient in the form of a GDI brush.
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_APPLICATION));
wcex.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_APPLICATION_SMALL));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_3DDKSHADOW + 1); // background brush
wcex.lpszMenuName = NULL;
wcex.lpszClassName = TEXT("My Colored Window Class");
RegisterClassEx(&wcex);
case WM_CTLCOLORSTATIC:
{
// NOTE: No leak here because we're using a system brush in this example.
return reinterpret_cast<LRESULT>(GetSysColorBrush(COLOR_3DDKSHADOW)); // background brush
}
                    
How can i remove white corner in combobox?
I don't know if there is a more official way to get rid of it, but one option would be to create a Region with rounded corners using CreateRoundRectRgn(), and then apply it to the ComboBox using SetWindowRgn(). That will mask off the corners.

Successful build with createWindowEx, window still won't appear

I'm trying to learn some windows and directX programming and I was messing around trying some different things. When suddently my the windows stopped appearing, even tho it was a successful build. I figured I must have messed something up and I undid everything until i got back to the place where I last managed to get the window to appear, but now when I run (with a successful build) it still doesn't show :( And I'm starting to run out of ideas what the problem could be, it so strange. One of the thing I did since last time I got it to work was add some libs directories but I have a hard time seeing how that would affect the program this way. Have anyone of you run in to this problem before, and if so how did you solve it? Here is the code of the func creating the window (and yes I am aware of the infinite loop, it shouldn't cause this problem tho, right?) :
ps. I have also tried changing between WINDCLASSEX and WINDCLASS, with all the functions that need to be change with it, didn't make any difference ds.
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow){
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
RegisterClass(&wc);
RECT wr = {0, 0, 500, 400}; // set the size, but not the position
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); // adjust the size
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"My first window", // Window text
WS_OVERLAPPEDWINDOW, // Window style
CW_USEDEFAULT, CW_USEDEFAULT,//position x,y
wr.right-wr.left, wr.bottom-wr.top,//width, height
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL){
return 0;
}
InitD3D(hwnd);
// Run the message loop.
MSG msg = { };
while (true){
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
}
}
return 0;
}
looks like you need a ShowWindow call in there (unless InitD3D does that, you haven't shown the code)
windows are by default created non-visible, so that you can do various initialization without the user seeing what goes on
as an alternative you can create the window already visible, but generally it's a good idea to keep to a single convention
by the way, you can just use a standard int main, no need to use the Microsoft monstrosity
with GNU toolchain that's all, with Microsoft's tools you then have to tell the linker to accept the standard code, if you use the GUI subsystem, via linker option /entry:mainCRTStartup.
also, the call to non-blocking PeekMessage means your message loop will most likely be a CPU hog
instead, use blocking GetMessage
and remember to exit the loop when GetMessage returns 0 (which indicates a WM_QUIT message has been posted)

window with transparent client area

I register the window class like this:
WNDCLASSEX wctt;
wctt.cbSize = sizeof(WNDCLASSEX);
wctt.style = CS_DBLCLKS;
wctt.lpfnWndProc = WndProcTooltip;
wctt.cbClsExtra = 0;
wctt.cbWndExtra = 0;
wctt.hInstance = m_hAppInstance;
wctt.hIcon = NULL;
wctt.hCursor = LoadCursor(NULL, IDC_SIZE);
wctt.hbrBackground = NULL;
wctt.lpszMenuName = NULL;
wctt.lpszClassName = _T("myWindow");
wctt.hIconSm = NULL;
RegisterClassEx(&wctt)
As you can see I use wctt.hbrBackground = NULL; so it will have no background.
The window is created like this:
::CreateWindowEx(WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
_T("myWindow"),
NULL,
WS_VISIBLE | WS_POPUP,
50,
50,
150,
100,
NULL,
NULL,
m_hAppInstance,
NULL);
In the paint section I draw icon on the window:
PAINTSTRUCT ps;
HDC hdc;
BITMAP bitmap;
ICONINFO iconinfo;
hdc = ::BeginPaint(hWnd, &ps);
::SetBkMode(hdc,TRANSPARENT);
::GetIconInfo(localIcon, &iconinfo);
::GetObject(iconinfo.hbmColor, sizeof(bitmap), &bitmap);
::DeleteObject(iconinfo.hbmColor);
::DeleteObject(iconinfo.hbmMask);
::DrawIconEx(hdc, 0,0, localIcon, bitmap.bmWidth, bitmap.bmHeight, 0, NULL, DI_NORMAL);
The icon size is smaller than the window size and I get on the background the current view on the window below the popup.
But now when I move the window (or minimize the window below the popup) the background is not changing.
I was trying to make a timer that each time do the flowing:
RECT rcClient;
GetClientRect(hWnd, &rcClient);
InvalidateRect(hWnd,&rcClient,TRUE);
This makes the print function run again but the background of the icon is not changing.
Should I do anything in WM_ERASEBKGND?
Does Anyone have any idea how to make it work?
thanks,
guy
It's not enough to just let the background stay unpainted; you also need to get the window below yours to repaint itself when necessary.
If the windows are part of the same hierarchy, created by the same thread, it is sufficient to give your window the WS_EX_TRANSPARENT extended style. This causes the window underneath to paint itself first so the background is always up-to-date.
Otherwise you need to use SetWindowRgn so that your window actually doesn't exist outside of the borders you wish to paint.
Look at Layered Window. This feature allows creating semi-transparent windows of different shapes.
Add WS_EX_LAYERED extended attribute in your window class.
You can control the transparency of your window with these two functions:
SetLayeredWindowAttributes:
bAlpha controls the opacity of the entire window, if you pass LWA_ALPHA in dwFlags.
When bAlpha is 0, the window is completely transparent. When bAlpha is 255, the window is opaque.
crKey sets the color that would transparent.
All pixels painted by the window in this color will be transparent.
UpdateLayeredWindow gives you precise control over window transparency, you can give different parts of window different levels of transparency.
If you're trying to create a non-rectangular window, this is not sufficient. Setting "no background" simply means the background will not be drawn, and you'll see whatever happens to be in memory at that location.
To create a non-rectangular window, have a look at the SetWindowRgn function.

DialogBoxIndirect creates dialog bigger than asked

For my application I need to create a Dialog Box without using resource.
I am trying to do it with DialogBoxInderect function.
The code is unbelievably ugly but somehow I succeeded to do it.
The problem is that dialog, for some reason, is much bigger than I asked with much bigger fonts.
Here is how the dialog looks like if I load it from resource:
And here is the dialog with the same size stated when I call DialogBoxInderect function.
Here is how it is defined in code:
HGLOBAL hGlobal;
LPDLGTEMPLATE wlsDialogTemplate;
LPDLGITEMTEMPLATE wlsDialogItemTemplate;
LPWORD nextItem;
LPWSTR itemString;
int32_t itemStringLength;
// Check for memory allocation errors
hGlobal = GlobalAlloc(GMEM_ZEROINIT, 1024);
if (!hGlobal)
return -1;
wlsDialogTemplate = (LPDLGTEMPLATE)GlobalLock(hGlobal);
// Define a dialog box.
wlsDialogTemplate->style = WS_CAPTION;
wlsDialogTemplate->x = 0;
wlsDialogTemplate->y = 0;
wlsDialogTemplate->cx = 320;
wlsDialogTemplate->cy = 115;
GlobalUnlock(hGlobal);
retCode = DialogBoxIndirect(0, (LPDLGTEMPLATE)hGlobal, 0, ActivateWlsMsgDialog);
And here is how it is defined in RC file:
IDD_WLS_SMALL_MESSAGE_DLG DIALOGEX 0, 0, 320, 115
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",ID_CUSTOM_OK,175,95,120,15
PUSHBUTTON "Cancel",ID_CUSTOM_CANCEL,45,95,120,15
CTEXT "Static",IDC_HEADER_TEXT,120,10,170,70
CONTROL "",IDC_LOGO,"Static",SS_BITMAP,16,10,83,70
END
As you can see, the second dialog is much bigger than defined. I tried to play with various style flags but without any success (That is why there is red cross on the bigger dialog).
Any help with that?
Thanks!
The larger size is easy to explain. Windows automatically sizes the dialog in accordance with its font, and the larger dialog uses a different font. In fact, it is using the default system font (more info on the confusing issue of Windows dialog fonts is found in my answer here).
So the real issue to focus on is why it's using a different font, and fixing that will solve the size problem.
In the dialog box resource file, you specify the DS_SETFONT flag as one of the dialog box styles. According to the documentation, this flag
[i]ndicates that the header of the dialog box template (either standard or extended) contains additional data specifying the font to use for text in the client area and controls of the dialog box. If possible, the system selects a font according to the specified font data. The system passes a handle to the font to the dialog box and to each control by sending them the WM_SETFONT message.
So that explains why that one is displaying with the expected font.
The next logical question is what's different about your dynamically-created dialog template, shown with the DialogBoxIndirect function. The culprit is, once again, the DS_SETFONT flag, but in this case, the flag is absent. That means that the dialog doesn't contain any information about which font to use to display its controls, and the system defaults to the default system font (which is the ugly Windows 2.0-era font that you see in the second screenshot).
Once we've come to this understanding, the solution should be obvious: you need to tell the dialog which font you want it to use. There are two possible ways of doing so that come to mind:
You can set the DS_SETFONT flag and provide the font information in the header of the dialog box template as described in the above-linked documentation.
Or you can simply create and set the dialog's font in response to the WM_INITDIALOG message.
The latter is probably what you really want to do, as it allows you to use the actual system font (which, confusingly, is different from what I've been calling the "default" system font), which is Segoe UI in Windows Vista and later. Note that even in your first screenshot, it's using MS Sans Serif and therefore sticks out like a sore thumb in the Aero interface. Again, see this answer for more about fonts than you ever wanted to know and sample code for making this work. You'll need to make sure that you set the font for the dialog itself and all of its child controls.
I had played with DialogBoxIndirect (actually with DialogBoxIndirectParam), and here's the part of the code that sets the font. Observe the DS_SHELLFONT option.
LPWORD lpwAlign(LPWORD lpIn, int nAlignment)
{
return (LPWORD)(((ULONG_PTR)lpIn + nAlignment - 1) & -nAlignment);
}
LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner, LPMYMESSAGEPARAMS pParams)
{
WORD mem[1024]; // Buffer for dialog resource
LPDLGTEMPLATEW lpdt; // Pointer to heading resource structure
LPDLGITEMTEMPLATEW lpdit; // Pointer to current control
LPWORD lpw; // Cursor to resource buffer
LPWSTR lpwsz; // Cursor to resource buffer (of type WCHAR)
LPCWSTR lpwszCaption; // Aux pointer for text copying
LRESULT ret; // Function's return value
lpdt = (LPDLGTEMPLATEW)lpwAlign( mem, 4 );
//-----------------------
// Define a dialog box.
//-----------------------
lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION |
DS_MODALFRAME | DS_CENTER | DS_SHELLFONT;
lpdt->dwExtendedStyle = 0;
lpdt->cdit = 3; // number of controls
lpdt->x = 0; lpdt->y = 0;
lpdt->cx = 164; lpdt->cy = 49;
lpw = (LPWORD)(lpdt + 1);
// Dialog menu
*lpw++ = 0;
// Dialog class
*lpw++ = 0;
// Dialog title
for (lpwsz = (LPWSTR)lpw, lpwszCaption = L"Choose language";
*lpwsz++ = *lpwszCaption++;
);
lpw = (LPWORD)lpwsz;
// Dialog font
if ( lpdt->style & (DS_SETFONT | DS_SHELLFONT) )
{
// Size
*lpw++ = 8;
// Typeface name
for (lpwsz = (LPWSTR)lpw, lpwszCaption = L"MS Shell Dlg";
*lpwsz++ = *lpwszCaption++;
);
lpw = (LPWORD)lpwsz;
}
// Define the rest of the controls
...
ret = DialogBoxIndirectParamW( hinst, lpdt,
hwndOwner, MyMessageProc, (LPARAM)pParams );
return ret;
}
This can be solved in your dialog handler by looking for the WM_INITDIALOG message, and then setting the font for all the controls in the dialog.
int CALLBACK SetChildFont(HWND child, LPARAM font) {
SendMessage(child, WM_SETFONT, font, TRUE);
return TRUE;
}
static int CALLBACK MyMessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_INITDIALOG:
/* Set font for dialog and all child controls */
EnumChildWindows(hwnd, (WNDENUMPROC)SetChildFont, (LPARAM)GetStockObject(DEFAULT_GUI_FONT));
break;
}
return 0;
}

BringWindowToTop is Not working even if I get the handle to Class Window

I am registering my Class in the following method:
BOOL CNDSClientDlg::InitInstance()
{
//Register Window Updated on 16th Nov 2010, #Subhen
// Register our unique class name that we wish to use
WNDCLASS wndcls;
memset(&wndcls, 0, sizeof(WNDCLASS));
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndcls.lpszMenuName = NULL;
//Class name for using FindWindow later
wndcls.lpszClassName = _T("CNDSClientDlg");
// Register new class and exit if it fails
if(!AfxRegisterClass(&wndcls)) // [C]
{
return FALSE;
}
}
and then calling the InitInstance method and creating the window in constructor of the Class:
CNDSClientDlg::CNDSClientDlg(CWnd* pParent /*=NULL*/)
: CDialog(CNDSClientDlg::IDD, pParent)
{
InitInstance();
HWND hWnd;
hInst = AfxGetInstanceHandle(); // Store instance handle in our global variable
hWnd = CreateWindow(_T("CNDSClientDlg"), "NDS", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
}
Now in my other application I am finding the window and trying to bring to top:
Edit
Able to bring newlyCreated Windows with below code
CWnd *pWndPrev = NULL;
CWnd *FirstChildhWnd = NULL;
pWndPrev = CWnd::FindWindow(_T("CNDSClientDlg"),NULL);
if(pWndPrev != NULL)
{
//pWndPrev->BringWindowToTop();
WINDOWPLACEMENT wndplacement;
pWndPrev->GetWindowPlacement(&wndplacement);
wndplacement.showCmd = SW_RESTORE;
pWndPrev->SetWindowPlacement(&wndplacement);
pWndPrev->SetForegroundWindow();
FirstChildhWnd = pWndPrev->GetLastActivePopup();
if (pWndPrev != FirstChildhWnd)
{
// a pop-up window is active, bring it to the top too
FirstChildhWnd->GetWindowPlacement(&wndplacement);
wndplacement.showCmd = SW_RESTORE;
FirstChildhWnd->SetWindowPlacement(&wndplacement);
FirstChildhWnd->SetForegroundWindow();
}
I am able to find the window as pWndPrev is not NULL , but It is not bringing up my application to front. Do I need to register any other class Instead of CNDSClientDlg. I want to bring my MFC application to top.
A few things to look at...
1) Try SetForegroundWindow() instead of BringWindowToTop(). It's been awhile since I've done Win32 programming, but I seem to recall that BringWindowToTop() has some limitations (especially when working with windows in different processes).
2) There are some rules that Microsoft put in place regarding SetForegroundWindow() starting with Windows 2000. The short version is that only the front-most application can change the foreground window. The idea is that an application that is not front-most cannot "jump in front of" the active application. If a background application calls SetForegroundWindow(), Windows will flash the taskbar button for the app, but will not actually bring the app to the front. The user must do that. I'm oversimplifying the rules, but this may be something to look at depending on your specific scenario.
BringWindowToTop() only works if the calling process is the foreground process or if it received the last input event.
Call CWnd::SetForegroundWindow() instead.
You may need to call AllowSetForegroundWindow in your "other" application before calling SetForegroundWindow.
That is assuming your other application is the foreground app and is trying to pass on its foreground status to the application with the window.
If neither app is the foreground app then you're not supposed to be able to bring a window to the front, although there are ways to do it (both accidentally and on purpose).
SetWindowPos(&wndTopMost, -1, -1, -1, -1, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
SetForegroundWindow();