I'm trying to make it so that a user can select text from a read-only edit box, but he won't see the blinking caret. I've been able to make the caret disappear from the edit, but it can still be seen for an instant.
This is my code for the subclass:
LRESULT CALLBACK UserInfoProc (HWND hUserInfoWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
HideCaret(hUserInfoWnd);
return DefSubclassProc(hUserInfoWnd, uMsg, wParam, lParam);
}
It's a modest bit of code, I know, but it almost does what I want.
So what happens is, that when I click the edit, the caret can be seen for an instant (50ms?). I want that it doesn't appear at all. How can I do this? I want the user to still be able to select the text from the edit.
You could try moving the HideCaret() call to after the DefSubclassProc(), since at the moment if a message triggers the caret it won't be until the next message that it's hidden again.
Also, I would guess that the only message that triggers the caret to be shown is WM_SETFOCUS, so you may want to test for that message only. For example,
LRESULT CALLBACK UserInfoProc (HWND hUserInfoWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
LRESULT lRes = DefSubclassProc(hUserInfoWnd, uMsg, wParam, lParam);
if (uMsg == WM_SETFOCUS) // maybe?
HideCaret(hUserInfoWnd);
return lRes;
}
Related
I apologize if I'm overlooking something, but I'm trying to just create a placeholder window within an ATL dialog, which will be used to host a preview handler. I thought placing a custom control might be the thing to do, since it's blank and would occupy a designated place, but that's causing the dialog to crash, and I get the feeling doing something with a custom control is more complicated than I'm looking for. So is there a way to just put a dummy window inside a dialog for use as a host site? Thanks for any input.
Update: I seem to have achieved the desired result using a simple blank picture control. But I'm still wondering if there's a more official way of doing this.
for placeholder we need use exactly custom control. the point - need specify window class name. and this class must be registered.
let name of class will be MyClass
so in .rc file must be
CONTROL "Custom1",IDC_CUSTOM1,"MyClass",...
and we need register "MyClass", minimal code
class MyWndCls
{
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_NCDESTROY:
delete this;
break;
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
static LRESULT CALLBACK _WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return reinterpret_cast<MyWndCls*>(GetWindowLongPtrW(hwnd, GWLP_USERDATA))->WindowProc(hwnd, uMsg, wParam, lParam);
}
static LRESULT CALLBACK StartWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_NCCREATE)
{
if (MyWndCls* p = new MyWndCls)
{
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)p);
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)_WindowProc);
return p->WindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
inline static const WCHAR clsname[] = L"MyClass";
public:
static ULONG Register()
{
WNDCLASS wndcls = {
0, StartWindowProc, 0, 0, (HINSTANCE)&__ImageBase, 0,
LoadCursorW(0, IDC_HAND), (HBRUSH)(COLOR_INFOBK + 1), 0, clsname
};
return RegisterClassW(&wndcls) ? NOERROR : GetLastError();
}
static ULONG Unregister()
{
return UnregisterClassW(clsname, (HINSTANCE)&__ImageBase) ? NOERROR : GetLastError();
}
};
of course we need call MyWndCls::Register(); before create any dialog with this custom control
I am currently trying to create a modal dialog in my application, like this:
RedditRefresherLoginDialog loginDialog;
loginDialog.DoModal();
However, as soon as my code reached the DoModal(), I always get an Assertion:
Debug assertion failed:
atlwin.h
Line: 3191
Expression: 0
My Dialog class looks like this:
class RedditRefresherLoginDialog : public CDialogImpl<RedditRefresherLoginDialog>, public CWinDataExchange<RedditRefresherLoginDialog>
{
public:
RedditRefresherLoginDialog();
~RedditRefresherLoginDialog();
enum { IDD = IDD_REDDITREFRESHERLOGINDIALOG };
BEGIN_MSG_MAP_EX(RedditRefresherLoginDialog)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_INITDIALOG, OnInit)
COMMAND_ID_HANDLER_EX(IDC_EXIT, OnExitButtonClick)
END_MSG_MAP()
LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnInit(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
private:
void OnExitButtonClick(UINT uCode, int nCtrlID, HWND hwndCtrl);
};
The assert is caused in the atlwin.h, ~CWindowImplRoot() deconstructor.
if(m_hWnd != NULL) // should be cleared in WindowProc
{
ATLTRACE(atlTraceWindowing, 0, _T("ERROR - Object deleted before window was destroyed\n"));
ATLASSERT(FALSE);
}
Due to the assert being hit in CWindowImpl, I tried to add inheritance from public CWindowImpl<RedditRefresherLoginDialog> and remove the CDialogImpl instead, but then, DoModal doesn't work anymore.
Does anyone know how to fix this?
I have a multiline Edit control that allow to multiline text from other source (i.e copy/paste,...) but I don't want to allow user have new line by press Enter key directly.
How can I handle Enter key in this case? Thank!
You can do this with a simple sub-class of the edit control that blocks the return key:
LRESULT CALLBACK EditSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
if (uMsg == WM_CHAR && wParam == VK_RETURN)
return 0;
LRESULT lRes = DefSubclassProc(hWnd, uMsg, wParam, lParam);
if (uMsg == WM_DESTROY)
RemoveWindowSubclass(hWnd, EditSubclassProc, 0);
return lRes;
}
To invoke it:
SetWindowSubclass(hWndEdit, EditSubclassProc, 0, 0);
i want to learn a bit about how to use hooks so im trying to make a program that will change the input of 'A' to 'B',
i'm trying to use the WH_KEYBOARD hook and according to msdn:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644984(v=vs.85).aspx
the WParam is "The virtual-key code of the key that generated the keystroke message.", so i tried to change it and use callNextHook.
LRESULT CALLBACK KeyboardProc(
_In_ int code,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
if (wParam == 65)
wParam++;
CallNextHookEx(NULL, ncode, wParam, lParam);
}
i have tried to do something like that, and even without the "if" the changing of wParam doesn't affects the result.
what did i do wrong here? how can i make it to work?
thank you
I have been having trouble with my program trying to gray out ( and disable ) a sub menu item.
What I'm looking for is that the "run" item be disabled unless the required .ini entry is not empty.
My code
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HMENU hmenu = GetMenu(hWnd);
// Reading in ini
if (0 == strcmp(webLocation, "")){
EnableMenuItem(hmenu,ID_WEBSERVICES_RUN,MF_DISABLED | MF_GRAYED);
WritePrivateProfileString(_T("WEBSERVICES"), _T("Location"), _T("Tool Not Found"), WpathStr);
}
I am unsure as to whether I am getting the HMENU correctly and why this code is not working for the desired effect.
Any help with this would be greatly appreciated.
You can't just put this in the WndProc at the top level. WndProc process events, whether the window has been constructed or not. It'll be called many times for many different reasons.
Your WndProc will almost certainly look like a big switch on message. The one you want here is WM_INITDIALOG:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
// jump to a new function that reads the .ini
// and disables the control etc.
return OnInitDialog(hWnd, wParam, lParam);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}