create a CAxWindow inside a BHO (C++) - c++

I'm having trouble opening a new CAxWindow inside my BHO, I can see the request to "microsoft.com" being fired but no window is shown.
I tried many different ways, this is my last, anyone has a clue what's wrong?
thanks.
CAxWindow m_axWindow;
CRect rc;
HWND wndIE = NULL;
m_pWebBrowser->get_HWND((SHANDLE_PTR*)&wndIE);
GetWindowRect(wndIE, &rc);
CSize sz = CSize(100, 200);
CRect rcPage = new CRect(10, 10, 10, 10);
m_axWindow.Create(wndIE, rcPage, _TEXT("http://www.microsoft.com"), WS_POPUP | WS_TABSTOP, 0, 0U, 0);
HRESULT hRet = m_axWindow.QueryControl(IID_IWebBrowser2, (void**)&m_pWebBrowser);

I think m_axWindow.Create creates a child window. Check its style for WS_CHILD after that call. You probably need to create a plain popup top-level window first, then create a CAxWindow using that popup window as parent, not the wndIE. Make sure to do ShowWindow on the pop-up, too.

Related

Who should be the parent of a tab control child dialog?

According to some sources, a tab child dialog should be the child of the actual main dialog window, not the tab control itself. I think some of the docs suggest the opposite, namely this function example:
// Creates a child window (a static control) to occupy the tab control's
// display area.
// Returns the handle to the static control.
// hwndTab - handle of the tab control.
//
HWND DoCreateDisplayWindow(HWND hwndTab)
{
HWND hwndStatic = CreateWindow(WC_STATIC, L"",
WS_CHILD | WS_VISIBLE | WS_BORDER,
100, 100, 100, 100, // Position and dimensions; example only.
hwndTab, NULL, g_hInst, // g_hInst is the global instance handle
NULL);
return hwndStatic;
}
So is there a definitive view on this? I checked Petzold, by the way, but didn't locate anything on the subject. Thanks for any help.

how to change the position of the child window inside the parent window and show the toolbar?

I have the following code which passes a window handler form OpenCV window to win32 handler, therefore I can show the grabbed images from camera to the screen and the images will show as a child window of my main API.
but the problem is that when I want to add a tooldbar to my program, the image window handler comes at the top of the toolbar. how can I sort this out?
//create a window and set the handler from openCV to win32
cv::namedWindow("test",cv::WINDOW_AUTOSIZE);
hWnd2 = (HWND) cvGetWindowHandle("test");
hParent = ::GetParent(hWnd2);
::SetParent(hWnd2, hWnd);
::ShowWindow(hParent, SW_HIDE);
_liveCapturing=true;
lastPicNr = 0;
SetWindowTextW(hStatus, L"Live Capturing ... ");
if(FullScreen()){
::ShowWindow(hWnd, SW_MAXIMIZE);
}
code for the toolbar :
HWND CreateToolbar(HWND hwnd){
HWND hTbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | CCS_TOP , 0, 0, 0, 0, hwnd, (HMENU)12, GetModuleHandle(NULL), NULL);
SendMessage(hTbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
TBBUTTON tbb[3];
TBADDBITMAP tbab;
tbab.hInst = HINST_COMMCTRL;
tbab.nID = IDB_STD_SMALL_COLOR;
SendMessage(hTbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);
return hTbar;
}
Probably you have found the solution a long time ago, but i want to post my anwers in case other users need it.
You can simply add the OpenCV window with the same code you have to a child window in your window (which you set it position in advance). For example you can add it to a static text window (label) ...
If you want to move the OpenCV window, call SetWindowPos() with the desired coordinates.
SetWindowPos(hWnd2, 0, 0, 30, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

How to resolve aliased text in MFC controls

I'm currently in the second stage of development for a data management project I'm involved with; at the moment, we're in the stage of revamping the GUI (we're going for an office 2007-themed GUI).
At the moment I've only got experience with Dialog-based MFC projects, from which this migrates from, where we drew controls onto the dialog, then got handles to them using the GetDlgItem command, using the IDs of the controls.
Now, we're using SDI, instead of a dialog-based project, and thus, it's required to procedurally create the controls. I've had no problems creating and showing controls in the ChildView area; however, the text is very low quality and aliased. I googled the problem, but was unable to find anything particularly pertinent to the problem, indeed, the only thing which bore any real relevance was using GDI+ to draw anti-aliased text, which is fine for simple text, but I need MFC controls such as CEdit and CListBox.
Here is an image to help illustrate my problem:
I am creating both the static GDI+ text and the MFC control in the OnPaint function, as follows:
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
Gdiplus::Graphics graphics(dc);
static Gdiplus::FontFamily* fontFamily = new Gdiplus::FontFamily( _T("Segoe UI") );
static Gdiplus::Font* font = new Gdiplus::Font( fontFamily, 12, Gdiplus::FontStyle::FontStyleRegular, Gdiplus::Unit::UnitPixel );
static Gdiplus::SolidBrush* solidBrush = new Gdiplus::SolidBrush( Gdiplus::Color::RoyalBlue );
Gdiplus::PointF point( 10, 10 );
graphics.SetTextRenderingHint( Gdiplus::TextRenderingHint::TextRenderingHintAntiAlias );
graphics.DrawString( _T("Hello, World!"), 13, font, point, solidBrush );
// TODO: Add your message handler code here
CEdit* pEditBox = new CEdit();
pEditBox->CreateEx( WS_EX_CLIENTEDGE, _T("EDIT"), _T("Why is this text so poor?"), WS_BORDER | WS_CHILD | WS_VISIBLE, CRect(100, 100, 300, 200), this, UINT_MAX-9 );
// Do not call CWnd::OnPaint() for painting messages
}
At the moment, I am wondering if it necessary to derive each of the controls and change their rendering methods to use GDI+ antialiased text. Hopefully their is an easier way to resolve this problem.
I will be extremely grateful for any help/advice.
Thanks in advance!
EDIT: Just for reference, I used to following to resolve my problem:
CFont* pFont = new CFont();
pFont->CreatePointFont( 120, _T("Segoe UI") );
CEdit* pEditBox = new CEdit();
pEditBox->CreateEx( WS_EX_CLIENTEDGE, _T("EDIT"), _T("Test Edit"), WS_BORDER | WS_CHILD | WS_VISIBLE, CRect(100, 100, 300, 200), this, UINT_MAX-9 );
pEditBox->SetFont( pFont );
Alternatively, the following allows for the default font for the window to be used:
CEdit* pEditBox = new CEdit();
pEditBox->CreateEx( WS_EX_CLIENTEDGE, _T("EDIT"), _T("This text is no longer poor"), WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE, CRect(100, 100, 300, 200), this, UINT_MAX-9 );
if( ::IsWindow( pEditBox->GetSafeHwnd() ) )
{
::SendMessage( pEditBox->GetSafeHwnd(), WM_SETFONT, (WPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), FALSE );
}
Change the font used by the edit box, it's just the default one that looks so ugly.
If you want to get the "standard" font, see e.g. SystemParametersInfo with SPI_GETNONCLIENTMETRICS argument. Of course, you can use any other font if you want to.

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();

CDialog doesnt show in task bar

Im trying to get a CDialog that has no border or frame to show in the task bar.
It is created in the InitInstance of CWinApp (used to update the app) and i have tried setting the WS_EX_APPWINDOW flag but it still doesnt show in the task bar.
Any ideas?
Edit:
As defined in the resource:
IDD_UPDATEFORM_DIALOG DIALOGEX 0, 0, 246, 124
STYLE WS_POPUP
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
END
As used:
UpdateForm *dlg = new UpdateForm(UPDATE_FILES, CWnd::GetDesktopWindow());
INT_PTR nResponse = dlg->DoModal();
UpdateForm::UpdateForm(int updateType, CWnd* pParent) : CDialog(IDD_UPDATEFORM_DIALOG, pParent)
{
m_bInit = false;
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON);
m_Progress = new DesuraProgress();
m_updateType = updateType;
}
Still Shows up like so:
http://update.goldeneyesource.net/lodle/noicon.jpg http://update.goldeneyesource.net/lodle/noicon.jpg
Edit #2:
To set the icon for this window (essentially a splash screen), you can send the window a WM_SETICON message along with a desired icon.
For a dialog, you can do this in OnInitDialog(). Here's a snippet that uses the default windows information icon as noted here: LoadIcon # MSDN.
// CHelperDlg message handlers
BOOL CHelperDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 32516 is also known as IDI_INFORMATION
HICON hIcon = LoadIcon(0, MAKEINTRESOURCE(32516));
// 0 in WPARAM is 'small version'
::SendMessage(GetSafeHwnd(), WM_SETICON, 0, (LPARAM)hIcon);
// 1 in WPARAM is 'large version'
::SendMessage(GetSafeHwnd(), WM_SETICON, 1, (LPARAM)hIcon);
// No cleanup as HICONs are free from disposal rules.
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
--
Edit:
I created a second project to mimic your update, but I don't see any differences except the inclusion of DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS) in my .rc file. These dialog style definitions don't affect the display of the dialog.
I've uploaded key parts for my minimal example to http://gist.github.com/461057 for your reference, in case you'd like to try adding this dialog ahead of yours for testing.
Also, I'm using VS2010. I have VS2008 available if you'd like me to repeat this test in that version as well.
--
Original:
Try specifying the desktop window (via CWnd::GetDesktopWindow()) as the parent window when you create the dialog.
// Member Variable
CHelperDlg *dlg;
// Meanwhile, elsewhere...
dlg = new CHelperDlg();
dlg->Create(IDD_HELPERDLG, CWnd::GetDesktopWindow());
dlg->ShowWindow(SW_SHOW);
// or...
// dlg->DoModal();
Also, don't forget to destroy the dialog when you're done with it, either in the destructor of the class owner, or other convenient location.
I figured out a hack to get this to work. Instead of disabling the toolbar/caption bar styles to get no border, i used SetWindowRgn to clip the frame and title bar. Same affect, less issues.
RECT rect;
GetWindowRect(&rect);
int w = rect.right - rect.left;
int h = rect.bottom - rect.top;
HRGN region = CreateRoundRectRgn(5, 30, w-5, h-5-30, 5, 5);
SetWindowRgn(region, true);