I'v create an Edit control dynamic by calling the constructor function and the Create function of CEdit:
m_pMyEdit = new CEdit;
m_pMyEdit->Create(style,zindex,100,100,100,100,pParentWindow,ID);
As you know, we can pass the this to the parent window parameter or set this parameter to another window. In my code, I passed the parent window parameter the value of:
CWnd::FromHandle(GetDesktopWindow())
This piece of code can get a pointer of CWnd (CWnd*) from the specific handle. Now run program and the Edit window shows at the position as we expect, and the caret shows in the Edit control and the focus is activited. But when I moved this edit to somewhere else, for example, move it to:
RECT rect = {200,200,100,100};
the caret disappear and the focus has been killed, further more, when I move the cursor on it, click mouse, the caret not appear and the focus not set any more. I have read the MSDN again and again, but I don't know why this happens.
By the way, the m_pMyEdit is the var of CEdit, I haven't derived the CEdit class yet.
Related
I noticed that when I call DoModal() on a CDialogImpl, atlwin.h calls:
return ::DialogBoxParam(_AtlBaseModule.GetResourceInstance(),
MAKEINTRESOURCE(static_cast<T*>(this)->IDD),
hWndParent,
T::StartDialogProc,
dwInitParam);
Which retrieves the dialog box information from the DIALOGEX description in the .rc file.
I can't see how to add a CLASS item to this structure to set the window class to a custom one, as I need the T::StartDialogProc. When I put in the T::StartDialogProc for ATL::CDialogImpl<MyClass>, DialogBoxParam() throws an Access Violation exception. I have to assume this is some kind of thunking problem.
My motivation is, I have a specific issue with the IDC_WAIT cursor being shown for a few milliseconds (it "flashes up" when I call DoModal()) and my working theory right now is that my DIALOGEX doesn't have a default cursor. The reason I think this is because when I do the following in my WM_INITDIALOG handler:
SetClassLong(m_hWnd, GCL_HCURSOR, (LONG) ::SetCursor(::LoadCursor(0, IDC_ARROW)));
The problem is minimized, ie the cursor sometimes briefly flashes to wait. I think if it had a default cursor before it arrived at WM_INITDIALOG, ie from the window class, the problem will disappear completely.
So, is it possible to add a custom window class to a CDialogImpl, or to add a default cursor to the class that CDialogImpl uses? If so, how?
I have seen several tools adding a custom button and/or drawing on the title bar of all windows of all applications in Windows. How is that done?
Extra points for an example in Delphi.
EDIT:
I found something for dotNET that does this:
http://www.thecodeking.co.uk/2007/09/adding-caption-buttons-to-non-client.html#.VdmioEDenqQ
How I see this job:
First of all we should be able to paint this button on the our own window caption. This procedure will be used later
This part of the program enumerates the active and visible windows
This part of the program using injection attach our dll to enumerated windows
From injected dll we can draw the button on the window caption
Inside this dll we should process the click on the button
We should have mechanism to send result to our main program
I haven't done this, so the following is what I would investigate if I were to try:
For each application / each top-level window:
Create a floating window and position it over the title bar wherever you want it to sit. Set up the parent / child relationship, but this window is part of your own process. (There are occasionally problems parenting a window from one process to one from another process, but try. I'd avoid injecting into other processes if possible.)
You can investigate the window flags to see if the window has a title bar (ie if you should add a button) via GetWindowLong with GWL_STYLE looking for WS_CAPTION. The same call will also let you see the type of caption / frame, which you can combine with GetSystemMetrics with, eg, SM_CYDLGFRAME to figure out the right size for your button on this specific window's title bar.
This window is now your button: paint, handle clicks etc as appropriate.
Make it a non-focusable window so that clicks to it don't take focus away from the window is is on the title bar of. You don't want clicking it to make the title bar change colour, for example. Do this by setting the WS_EX_NOACTIVATE window flag, something like: SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) orWS_EX_NOACTIVATE).
The main problem is to keep it positioned correctly when the window moves, is resized, etc. To do this, install a hook for the system move events. You can also hook minimize and restore via EVENT_SYSTEM_MINIMIZESTART and EVENT_SYSTEM_MINIMIZEEND. This will allow you to keep track of all windows moving around onscreen, such that you can adjust the button-window position if necessary.
That gives you a window which you can paint as a button (and respond to clicks etc), that visually is "attached" to other windows so it stays in the same place as the user drags the title bar, minimizes or maximises the app, etc, and that is in your own process without cross-process problems.
I'm learning Win32 assembly. Have some question I search but not suitable result.
Anyone can explain for me What difference between control's window handle and controlID.
They have nothing in common. Every window has a handle, returned by CreateWindowEx(). Such a window can have a few extra properties attached, like a menu handle. The hMenu argument in CreateWindowEx(). If the window doesn't have a menu, a child window won't have one, then you can use that argument to pass an arbitrary other bit of data. It will be assigned to the GWLP_ID property (see GetWindowLongPtr). Also note the GWLP_USERDATA, an extra property that's entirely yours to use as you see fit.
Dialogs take advantage of this, a dialog template that you create in the resource editor gives you a way to number the child controls. With a helper function like GetDlgItem() to get the handle back for a control with a specific number. Which is pretty necessary for dialogs since it is Windows that create the child controls from the dialog template so you don't know the window handles for them yourself.
I was reading about toolbars, and I came across this
Let's say you've derived a toolbar class named CStyleBar from CToolBar that includes a combo box with a list of all the fonts installed in the system. As the user moves the caret through a document, you want to update the combo box so that the item selected in it is the name of the typeface at the current caret position. Rather than respond to each change in the caret position by updating the combo box selection directly, you can override OnUpdateCmdUI as shown here:
void CStyleBar::OnUpdateCmdUI (CFrameWnd* pTarget,
BOOL bDisableIfNoHndler)
{
CToolBar::OnUpdateCmdUI (pTarget, bDisableIfNoHndler);
CString string = GetTypefaceAtCaret ();
if (m_wndComboBox.SelectString (-1, string) == CB_ERR)
m_wndComboBox.SetCurSel (-1);
}
So, the only thing confusing me is, how come moving caret throught the document call OnUpdateCmdUI? and if it doesn't calls OnUpdateCmdUI what else does moving caret thru the document calls?
Any help is appreciated.
Regards.
Moving the caret does not call OnUpdateCmdUI.
According to "The MFC Answer Book", when CWinThread::Run() finds there are no more messages to process, calls CWinThread::OnIdle() which sends WM_IDLEUPDATECMDUI messages to the frame window and all of its children. After a couple more functions, CToolBar::OnUpdateCmdUI() is called.
So, moving the caret does not call the function. It's the main loop, when idle, who asks the mainframe and its children to update themshelves.
Context:
I use glfw under xmonad. Glfw apparently sets the window title after creating the window, thus not allowing xmonad to properly handle it. I want to modify the glfw source so that I can set the window title before creating the window.
Problem:
So I download glfw-2.6, and I look into lib/x11/x11_window.c ; the lines causing the trouble are:
// Create a window
_glfwWin.Win = XCreateWindow(
_glfwLibrary.Dpy,
RootWindow( _glfwLibrary.Dpy, _glfwWin.VI->screen ),
0, 0, // Upper left corner
_glfwWin.Width, _glfwWin.Height, // Width, height
0, // Borderwidth
_glfwWin.VI->depth, // Depth
InputOutput,
_glfwWin.VI->visual,
CWBorderPixel | CWColormap | CWEventMask,
&wa
);
Followed sometime later by:
_glfwPlatformSetWindowTitle( "GLFW Window" );
where
void _glfwPlatformSetWindowTitle( const char *title )
{
// Set window & icon title
XStoreName( _glfwLibrary.Dpy, _glfwWin.Win, title );
XSetIconName( _glfwLibrary.Dpy, _glfwWin.Win, title );
}
Now, if I tr yto move the glfwPlatformSetWindowTitle call before the CreateWindow call, I get a segfault -- as I should, since _glfwWin.win would not be defined.
I don't know how to solve this problem since to set the window title, I need _glfwWin.Win to be initialized, but to initialize it, I need to create the window.
Thus, I ask: in X11, what is the proper way to set the window title before creating the window?
Thanks!
This is not possible in X11, but also not necessary for stuff to work. There must be a bug somewhere causing the symptoms you're seeing. The window title is just a property on the window, and properties can't exist until there's a window for them to be on.
You say "not allowing xmonad to properly handle it" which implies it isn't coping with changes to the name; window managers absolutely must handle setting the title at any time, including changing the title long after a window is created.
What the spec says (http://www.x.org/docs/ICCCM/icccm.pdf) is:
"The window manager will examine the contents of these properties when the window makes the
transition from the Withdrawn state and will monitor some properties for changes while the window is in the Iconic or Normal state."
The "transition from the Withdrawn state" is the point where glfw calls XMapWindow(). At that point, the window will remain unmapped but the WM will receive a MapRequest. The WM would then read properties and such and then map the window. All window managers I've ever seen also handle later changes to the property because changing the window title is pretty normal. For example web browsers the page title on every url.
If xmonad doesn't handle changes maybe it at least waits for the map, so maybe you just need to set title before XMapWindow(). Really all setup should be done before MapWindow though only a few properties are required to be before it by the specs. The props that must be before it generally can't be changed without unmapping.
Incidentally, _glfwPlatformSetWindowTitle won't work for anything but Latin-1. The modern way to do it is to set _NET_WM_NAME and _NET_WM_ICON_NAME with XChangeProperty() (setting the old Latin-1 WM_NAME is fine too but only as a fallback).