QT - Lost keyboard control when embedding application into QApplication - windows

I'm using Qt 5.2 and trying to embed notepad.exe into a widget in my QApplication.
my code is:
HWND winHandle = ::FindWindowA(NULL, "Untitled - Notepad");
if(winHandle != NULL)
{
QWindow * window = QWindow::fromWinId((WId) winHandle);
QWidget * notepadWidget = QWidget::createWindowContainer(window);
notepadWidget ->setParent( ui->widget);
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(notepadWidget);
ui->widget->setLayout(layout);
}
the notepad window is embedded beautifully into my application, but i lost the keyboard! i cannot type inside notepad. the mouse is working properly(i can select text, etc.)
anyone?

Related

How to check if a button is checkbox on 64 bit windows?

I'm checking if a button is checkbox of 32bit process on 64bit windows10.
The problem is that I can not distingush checkbox from normal button.
The buttons are different in Window-Detective:
(After I restart the application, even Window-Detective shows it is a button now!)
But the checkbox can't be recognized as checkbox in Spy++
BS_CHECKBOX is not listed.
Code (compiled as 32bit):
TEST_METHOD(ShouldCheckStyle) {
auto styleOfButton = ::GetWindowLongPtr((HWND)0x003F06E8, GWL_STYLE);
auto styleOfCheckbox = ::GetWindowLongPtr((HWND)0x01101642, GWL_STYLE);
auto bsOfButton = styleOfButton & BS_TYPEMASK;
auto bsOfCheckbox = styleOfCheckbox & BS_TYPEMASK;
auto resultOfButton = (bsOfButton == BS_CHECKBOX);
auto resultOfCheckbox = (bsOfCheckbox == BS_CHECKBOX);
auto debugger = 0;
}
Debug output
The code indicates they both have BS_OWNERDRAW. The above behaves the same for the button and the checkbox.
The weird thing is Window-Detective can recognize the style of checkbox. The code is same as I used above. Here's a piece of code:
Window* WindowManager::createWindow(HWND handle) {
WindowClass* windowClass = getWindowClassFor(handle);
String className = windowClass->getName().toLower();
if (className == "button") {
LONG typeStyle = GetWindowLong(handle, GWL_STYLE) & BS_TYPEMASK;
switch (typeStyle) {
case BS_CHECKBOX:
case BS_AUTOCHECKBOX:
case BS_3STATE:
case BS_AUTO3STATE: {
return new CheckBox(handle, windowClass);
}
case BS_RADIOBUTTON:
case BS_AUTORADIOBUTTON: {
return new RadioButton(handle, windowClass);
}
case BS_GROUPBOX: {
return new GroupBox(handle, windowClass);
}
default: {
// If none of the above is true, then the control is just a Button
return new Button(handle, windowClass);
}
}
}
After some discussion, you can use GetWindowText to get the text from each control and compare the specific text.
BS_CHECKBOX cannot be detected from the properties of the "checkbox" control beacuse of BS_OWNERDRAW.
Creates an owner-drawn button. The owner window receives a WM_DRAWITEM
message when a visual aspect of the button has changed. Do not combine
the BS_OWNERDRAW style with any other button styles.
Try the below code:
WCHAR str1[20];
WCHAR str2[] = L"Agree me";
GetWindowText(hwnd_checkbox, str1, 256);
if (_tcscmp(str1, str2) == 0)
{
//it is checkbox
}
else
{
//it isn't checkbox
}
After you get the correct control handle of the checkbox, you can use SendDlgItemMessage or SendMessage to send BM_SETCHECK check message.
SendMessage(hwnd_checkbox, BM_SETCHECK, BST_CHECKED, 0);

Design Preamble Mac OS X Mas

I recently packaged my app for MAC Store and was rejected. Below is the message sent to me by review team. When i testing using development mode everything works fine but I can't picture where i am getting something wrong. Any idea would be appreciated. App was built using Electron.
Design Preamble
The user interface of your app is not consistent with the macOS Human
Interface Guidelines.
Specifically, we found that when the user closes the main application
window there is no menu item to re-open it.
Next Steps
It would be appropriate for the app to implement a Window menu that
lists the main window so it can be reopened, or provide similar
functionality in another menu item. macOS Human Interface Guidelines
state that "The menu bar [a]lways contains [a] Window menu".
Alternatively, if the application is a single-window app, it might be
appropriate to save data and quit the app when the main window is
closed.
For information on managing windows in macOS, please review the
following sections in Apple Human Interface Guidelines:
The Menu Bar and Its Menus
The Window Menu
The File Menu
Clicking in the Dock
Window Behavior
Please evaluate how you can
implement the appropriate changes, and resubmit your app for review.
The Problem is that after the Application is minimized by pressing the x button, there is no way for the user to open it again from the dock.
One way to fix this is to just terminate the Application when the x button is clicked.
I had the same issue and fixed it by adding this function in AppDelegate. This solution is for Swift 4.2
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
Now the Application terminates, when the x button is clicked.
If you are working with Xamarin, edit your AppDelegate.cs to create a menu to reopen the main window:
public class AppDelegate : FormsApplicationDelegate
{
NSWindow window;
public override NSWindow MainWindow
{
get
{
return window;
}
}
public AppDelegate()
{
var style = NSWindowStyle.Closable | NSWindowStyle.Resizable | NSWindowStyle.Titled;
var rect = new CoreGraphics.CGRect(100, 100, 1024, 768);
window = new NSWindow(rect, style, NSBackingStore.Buffered, false);
window.TitleVisibility = NSWindowTitleVisibility.Hidden;
}
private NSMenu MakeMainMenu()
{
// top bar app menu
NSMenu menubar = new NSMenu();
NSMenuItem appMenuItem = new NSMenuItem();
menubar.AddItem(appMenuItem);
NSMenu appMenu = new NSMenu();
appMenuItem.Submenu = appMenu;
// add separator
NSMenuItem separator = NSMenuItem.SeparatorItem;
appMenu.AddItem(separator);
// add open menu item
string openTitle = String.Format("Open {0}", "MyApp");
var openMenuItem = new NSMenuItem(openTitle, "o", delegate
{
// Get new window
window.MakeKeyAndOrderFront(this);
});
appMenu.AddItem(openMenuItem);
// add quit menu item
string quitTitle = String.Format("Quit {0}", "MyApp");
var quitMenuItem = new NSMenuItem(quitTitle, "q", delegate
{
NSApplication.SharedApplication.Terminate(menubar);
});
appMenu.AddItem(quitMenuItem);
return menubar;
}
public override void DidFinishLaunching(NSNotification notification)
{
// finally add menu
NSApplication.SharedApplication.MainMenu = MakeMainMenu();
// Insert code here to initialize your application
Forms.Init();
//Load Application
LoadApplication(new App());
//Did Finish Launching
base.DidFinishLaunching(notification);
}
public override void WillTerminate(NSNotification notification)
{
// Insert code here to tear down your application
}
}
If you are workwing with Cocoa do the same but in the specific language.
Reopen the window with this instruction:
[window makeKeyAndOrderFront:self];
For electron apps you can add this code to your index.js or main.js to resolve the issue:
app.on('window-all-closed', () => {
app.quit();
});

Minimize window to system tray

I have created a SDL2 application, and would like it to minimize to the system tray, rather than appearing in the task bar.
SDL_MinimizeWindow doesn't do what I want, it leaves the task bar icon. Is there a way to achieve this with SDL?
There is no purely SDL2 way to do this, as Cody said, Shell_NotifyIcon is the function needed to create a notification area (system tray) icon.
The code I used to get the icon is
SDL_Window *window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 200, 200, SDL_WINDOW_HIDDEN);
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
NOTIFYICONDATA icon;
if (SDL_GetWindowWMInfo(window, &info))
{
icon.uCallbackMessage = WM_USER + 1;
icon.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
icon.hIcon = LoadIcon(NULL, IDI_INFORMATION);
icon.cbSize = sizeof(icon);
icon.hWnd = info.info.win.window;
strcpy_s(icon.szTip, "Test tip");
bool success = Shell_NotifyIcon(NIM_ADD, &icon);
}
This creates a hidden window, and an icon (using the default information icon).
To interact with this from SDL, you need to enable platform specific window management events, this is done as follows SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
After this, in the main event loop you must test for SDL_SYSWMEVENT, which contains information about how the user has interacted with the notification area icon. This also looks for the minimize event and hides the window which removes it from the task bar. This is achieved in the following snippet
SDL_Event e;
while (SDL_PollEvent(&e) != 0)
{
switch (e.type)
{
case SDL_SYSWMEVENT:
if (e.syswm.msg->msg.win.msg == WM_USER + 1)
{
if (LOWORD(e.syswm.msg->msg.win.lParam) == WM_LBUTTONDBLCLK)
{
SDL_ShowWindow(window);
SDL_RestoreWindow(window);
}
}
break;
case SDL_QUIT:
running = false;
break;
case SDL_WINDOWEVENT:
if (e.window.event == SDL_WINDOWEVENT_MINIMIZED)
SDL_HideWindow(window);
break;
}
}

Mfc Font binding and Rich Edit Control RICHEDIT50W does not display Unicode Properly

Latest update:
Well, I found a culprit of some sort. I changed the control to RichEdit20W from the 50W and it displays the Hangul (Korean) now. I did not have to change any other code except for the init, added AfxInitRichEdit2(), and commented out the LoadLibrary(L"MsftEdit.dll"). The AfxInitRichEdit5() is not available for VS2010. All things being equal and Rich Edit 4.1 has been available since VS2005, it should have worked. I can't upgrade to VS2015 right now so I'm stuck. I'm going to offer a bounty though for anybody who can make the Hangul work with 50W and VS2010.
I have a dilemma that I can't seem to solve.
I have an mfc Unicode app that uses CEdit and CRicheditCtrl.
The Rich Edit is 50W loaded from MsftEdit.dll and verified with Spy++
that the class name is RICHEDIT50W.
My problem:
I'm using the same Font Courier New for both the CEdit and CRichEditCtrl.
As a test, I used some of the Hangul symbols to see the output for both
controls.
CEdit outputs ᄀᄁᄂᄃᄄᄅᄆᄇᄈ
while the
CRichEditCtrl outputs a box for each character, like there is no glyph for it.
If they are using the same font, shouldn't I see the same output characters?
I think that font-binding is not a problem, both have the same default font.
Can anybody solve this riddle ?
Thanks in advance!
Note that this happens with some other character sets as well, not just Hangul
Update
I looked at the VS2010 WordPad example, it uses CRichEditView but it
provides wrappers to access the embedded CRichEditCtrl.
I thought I could glean some info but I can't see how they are doing the
Rich Edit control calls.
This is how I am generating the font's for both controls.
But, I'm showing specifically the Rich Edit part.
The doc's say that Font binding should handle switching from the default
font to the font at the current insertion point.
I am doing insertion mostly at the end using
ctrl.SetSel(-1,-1);
ctrl.ReplaceSel( str );
And, according to the doc's, this should change to the correct font as needed,
if other than the default font.
In the WordPad sample, if I paste in the Hangul text, the font switches to
Gulim.
Here is my code:
LOGFONT lf;
int pitch = 10;
memset(&lf, 0, sizeof(LOGFONT));
HDC hdc = ::GetDC(NULL);
lf.lfHeight = -MulDiv( pitch, GetDeviceCaps(hdc, LOGPIXELSY), 72);
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lstrcpy(lf.lfFaceName, _T("Courier New") );
lf.lfWeight = FW_NORMAL;
lf.lfCharSet = ANSI_CHARSET; // English, but use DEFAULT_CHARSET if not
lf.lfQuality = DEFAULT_QUALITY;
if ( !m_Font.CreateFontIndirect(&lf) )
{ // Ours didn't work, create a system default fixed font
// ( Ignore, example for post only. Never gets called though )
//memset(&lf, 0, sizeof(LOGFONT));
//::GetObject(GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT), &lf);
//m_Font.CreateFontIndirect(&lf);
}
// Save the generated Font LOGFONT
m_lf = lf;
// Set the default Font CHARFORMAT2
memset( &m_cfDefaultFont, 0, sizeof(m_cfDefaultFont) );
m_cfDefaultFont.cbSize = sizeof(m_cfDefaultFont);
m_cfDefaultFont.dwMask = CFM_CHARSET | CFM_FACE | CFM_WEIGHT ;
m_cfDefaultFont.bCharSet = m_lf.lfCharSet;
lstrcpy( m_cfDefaultFont.szFaceName, m_lf.lfFaceName );
m_cfDefaultFont.wWeight = m_lf.lfWeight;
// Finally set the font in the controls
m_RichEdit.SetFont( &m_Font );
// Same effect as m_RichEdit.SetFont()
//m_RichEdit.SendMessage(EM_SETCHARFORMAT, SCF_ALL, &m_cfDefaultFont);
// This displays nothing but 'box' glyphs
m_RichEdit.SetWindowTextW(_T("ᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎ"));
Update 2
This is how I initialize the Rich Edit in the app.
And shows the usage of 50W in a dialog control.
-- winapp.cpp
BOOL CMyApp::InitInstance()
{
// ...... //
CString strRichEdit = _T("Msftedit.dll");
m_hMsfteditDll = AfxLoadLibrary( strRichEdit );
if ( m_hMsfteditDll == NULL )
{
CString str;
str.Format(_T("Error: Cannot find Rich Edit component %s"), strRichEdit );
AfxMessageBox(str);
return FALSE;
}
return TRUE;
}
int CRegexFormatApp::ExitInstance()
{
if ( m_hMsfteditDll != NULL )
AfxFreeLibrary( m_hMsfteditDll );
return CWinAppEx::ExitInstance();
}
// =========================
-- .rc
CONTROL "",IDC_RICH_EDIT,"RICHEDIT50W",WS_VSCROLL | WS_HSCROLL,40,15,148,28
-- Dlg.h
CRichEditCtrl m_RichEdit;
-- Dlg.cpp
void Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_RICH_EDIT, m_RichEdit); // Use .rc setting to Create/Attach
}
BOOL Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
CreateAndSetRichFont(); // Code shown above
m_RichEdit.SetWindowTextW( ... );
}
This code should work in a Unicode project:
BOOL CMyApp::InitInstance()
{
CWinApp::InitInstance();
LoadLibrary(L"MsftEdit.dll");
...
}
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
static CRichEditCtrl redit;
CWnd *wnd = &redit;
wnd->Create(MSFTEDIT_CLASS, L"ᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎ",
WS_CHILD | WS_VISIBLE, CRect(0,0,300,300), this, 1001, 0);
...
//redit is not to be mixed up with controls created in dialog editor.
}
Edit ----------------
NONCLIENTMETRICS info = { sizeof(info) };
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
LOGFONT logfont = info.lfMessageFont;
//CClientDC has automatic cleanup, use it instead of GetDC
CClientDC dc(this);
logfont.lfHeight = -MulDiv(abs(logfont.lfHeight), dc.GetDeviceCaps(LOGPIXELSY), 76);
CFont font;
font.CreateFontIndirect(&logfont);
m_RichEdit.SetFont(&font);
m_RichEdit.SetWindowText(L"ᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎ");
m_RichEdit.SetSel(1, 1);
CString test = L"(Test, ελληνικά)";
//Test to make sure we can see Unicode text
AfxMessageBox(test);
m_RichEdit.ReplaceSel(test);
//optional:
//get default CHARFORMAT
CHARFORMAT2 charFormat;
//m_RichEdit.GetSelectionCharFormat(charFormat);
m_RichEdit.GetDefaultCharFormat(charFormat);

Qt4: QMenuBar/QMenu doesn't show up on Mac OS X

I'm having difficulties to make a QMenuBar display a QMenu with a QAction under Mac OS X (Snow Leopard).
Here is the code I'm using for creating the menu:
void ClientWindow::setUpMenu ()
{
QMenu * file = menuBar()->addMenu("&File");
QAction * quit = new QAction("&Quit", this);
file->addAction(quit);
connect(quit, SIGNAL(triggered()), this, SLOT(quit()));
}
Here is the ClientWindow class interface:
class ClientWindow : public QMainWindow
{
public:
ClientWindow (QWidget * parent = 0);
void setUpMenu ();
};
And here is my main() method:
int main (int argc, char * argv[])
{
QApplication app(argc, argv);
ClientWindow window;
window.setUpMenu();
window.show();
return app.exec();
}
Any ideas why it wouldn't show up on the menu bar?
Thank you all.
I solved the problem.
It appears that there is one action called "Quit" already, which is part of the default application's menu (every Mac OS X GUI app has such menu). This causes my attempt to add another action called "Quit" to be ignored by either Qt or the Window Server.
Simply renaming the action to "Close" solved the problem.
Some menupoints are automatically mapped to the mac osx native menu:
see http://doc.trolltech.com/4.6/mac-differences.html#menu-bar

Resources