annotate foosdk/sdk/libPPUI/InPlaceEdit.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "stdafx.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include "InPlaceEdit.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include "wtl-pp.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #include "win32_op.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 #include "AutoComplete.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 #include "CWindowCreateAndDelete.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #include "win32_utility.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 #include "listview_helper.h" // ListView_GetColumnCount
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 #include "clipboard.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 #include "DarkMode.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 #include <forward_list>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 using namespace InPlaceEdit;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 enum {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 MSG_COMPLETION = WM_USER,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 MSG_DISABLE_EDITING
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 // Rationale: more than one HWND on the list is extremely uncommon, hence forward_list
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 static std::forward_list<HWND> g_editboxes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 static HHOOK g_hook = NULL /*, g_keyHook = NULL*/;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 static void GAbortEditing(HWND edit, t_uint32 code) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 CWindow parent = ::GetParent(edit);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 parent.SendMessage(MSG_DISABLE_EDITING);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 parent.PostMessage(MSG_COMPLETION, code, 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 #if 0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 static void GAbortEditing(t_uint32 code) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 for (auto walk = g_editboxes.begin(); walk != g_editboxes.end(); ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 GAbortEditing(*walk, code);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 static bool IsSamePopup(CWindow wnd1, CWindow wnd2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 return pfc::findOwningPopup(wnd1) == pfc::findOwningPopup(wnd2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 static void MouseEventTest(HWND target, CPoint pt, bool isWheel) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 for (CWindow edit : g_editboxes) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 bool cancel = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 if (target != edit && IsSamePopup(target, edit)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 cancel = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 } else if (isWheel) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 CWindow target2 = WindowFromPoint(pt);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 if (target2 != edit && IsSamePopup(target2, edit)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 cancel = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 if (cancel) GAbortEditing(edit, KEditLostFocus);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 static LRESULT CALLBACK GMouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 if (nCode == HC_ACTION) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 const MOUSEHOOKSTRUCT * mhs = reinterpret_cast<const MOUSEHOOKSTRUCT *>(lParam);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 switch (wParam) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 case WM_NCLBUTTONDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 case WM_NCRBUTTONDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 case WM_NCMBUTTONDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 case WM_NCXBUTTONDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 case WM_LBUTTONDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 case WM_RBUTTONDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 case WM_MBUTTONDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 case WM_XBUTTONDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 MouseEventTest(mhs->hwnd, mhs->pt, false);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 case WM_MOUSEWHEEL:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 case WM_MOUSEHWHEEL:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 MouseEventTest(mhs->hwnd, mhs->pt, true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 return CallNextHookEx(g_hook, nCode, wParam, lParam);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 static void on_editbox_creation(HWND p_editbox) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 // PFC_ASSERT(core_api::is_main_thread());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 g_editboxes.push_front(p_editbox);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 if (g_hook == NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 g_hook = SetWindowsHookEx(WH_MOUSE, GMouseProc, NULL, GetCurrentThreadId());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 /*if (g_keyHook == NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 g_keyHook = SetWindowsHookEx(WH_KEYBOARD, GKeyboardProc, NULL, GetCurrentThreadId());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 }*/
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 static void UnhookHelper(HHOOK & hook) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 HHOOK v = pfc::replace_null_t(hook);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 if (v != NULL) UnhookWindowsHookEx(v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 static void on_editbox_destruction(HWND p_editbox) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 // PFC_ASSERT(core_api::is_main_thread());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 g_editboxes.remove(p_editbox);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 if (g_editboxes.empty()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 UnhookHelper(g_hook); /*UnhookHelper(g_keyHook);*/
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 class CInPlaceEditBox : public CWindowImpl<CInPlaceEditBox, CEdit> {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 CInPlaceEditBox(uint32_t flags) : m_flags(flags) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 BEGIN_MSG_MAP_EX(CInPlaceEditBox)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 //MSG_WM_CREATE(OnCreate)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 MSG_WM_DESTROY(OnDestroy)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 MSG_WM_GETDLGCODE(OnGetDlgCode)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 MSG_WM_KILLFOCUS(OnKillFocus)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 MSG_WM_CHAR(OnChar)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 MSG_WM_KEYDOWN(OnKeyDown)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 MSG_WM_PASTE(OnPaste)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 END_MSG_MAP()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 void OnCreation() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 on_editbox_creation(m_hWnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 void OnDestroy() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 m_selfDestruct = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 on_editbox_destruction(m_hWnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 SetMsgHandled(FALSE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 int OnCreate(LPCREATESTRUCT) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 OnCreation();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 SetMsgHandled(FALSE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 UINT OnGetDlgCode(LPMSG lpMsg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 if (lpMsg == NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 SetMsgHandled(FALSE); return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 switch (lpMsg->message) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 case WM_KEYDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 case WM_SYSKEYDOWN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 switch (lpMsg->wParam) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 case VK_TAB:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 case VK_ESCAPE:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 case VK_RETURN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 return DLGC_WANTMESSAGE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 SetMsgHandled(FALSE); return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 SetMsgHandled(FALSE); return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 void OnKillFocus(CWindow wndFocus) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 if ( wndFocus != NULL ) ForwardCompletion(KEditLostFocus);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 SetMsgHandled(FALSE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 bool testPaste(const char* str) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 if (m_flags & InPlaceEdit::KFlagNumberSigned) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 if (pfc::string_is_numeric(str)) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 if (str[0] == '-' && pfc::string_is_numeric(str + 1) && GetWindowTextLength() == 0) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 if (m_flags & InPlaceEdit::KFlagNumber) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 return pfc::string_is_numeric(str);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 void OnPaste() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 if (m_flags & (InPlaceEdit::KFlagNumber | InPlaceEdit::KFlagNumberSigned)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 pfc::string8 temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 ClipboardHelper::OpenScope scope; scope.Open(m_hWnd);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 if (ClipboardHelper::GetString(temp)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 if (!testPaste(temp)) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 // Let edit box handle it
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 SetMsgHandled(FALSE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 bool testChar(UINT nChar) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 // Allow various non text characters
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 if (nChar < ' ') return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 if (m_flags & InPlaceEdit::KFlagNumberSigned) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 if (pfc::char_is_numeric(nChar)) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 if (nChar == '-') {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 return GetWindowTextLength() == 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 if (m_flags & InPlaceEdit::KFlagNumber) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 return pfc::char_is_numeric(nChar);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 (void)nRepCnt; (void)nRepCnt;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 if (m_suppressChar != 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 UINT code = nFlags & 0xFF;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 if (code == m_suppressChar) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 if (!testChar(nChar)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 MessageBeep(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 SetMsgHandled(FALSE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 (void)nRepCnt;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 m_suppressChar = nFlags & 0xFF;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 switch (nChar) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 case VK_BACK:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 if (GetHotkeyModifierFlags() == MOD_CONTROL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 CEditPPHooks::DeleteLastWord(*this);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 case 'A':
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 if (GetHotkeyModifierFlags() == MOD_CONTROL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 this->SetSelAll(); return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 case VK_RETURN:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 if (!IsKeyPressed(VK_LCONTROL) && !IsKeyPressed(VK_RCONTROL)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 ForwardCompletion(KEditEnter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 case VK_TAB:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 ForwardCompletion(IsKeyPressed(VK_SHIFT) ? KEditShiftTab : KEditTab);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 case VK_ESCAPE:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 ForwardCompletion(KEditAborted);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 m_suppressChar = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 SetMsgHandled(FALSE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 void ForwardCompletion(t_uint32 code) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 if (IsWindowEnabled()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 CWindow owner = GetParent();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 owner.SendMessage(MSG_DISABLE_EDITING);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 owner.PostMessage(MSG_COMPLETION, code, 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 EnableWindow(FALSE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 const uint32_t m_flags;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 bool m_selfDestruct = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 UINT m_suppressChar = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 class InPlaceEditContainer : public CWindowImpl<InPlaceEditContainer> {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 DECLARE_WND_CLASS_EX(_T("{54340C80-248C-4b8e-8CD4-D624A8E9377B}"), 0, -1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 HWND Create(CWindow parent) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 RECT rect_cropped;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 RECT client;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 WIN32_OP_D(parent.GetClientRect(&client));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 IntersectRect(&rect_cropped, &client, &m_initRect);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 const DWORD containerStyle = WS_BORDER | WS_CHILD;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 AdjustWindowRect(&rect_cropped, containerStyle, FALSE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 WIN32_OP(__super::Create(parent, rect_cropped, NULL, containerStyle) != NULL);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 CRect rcClient;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 WIN32_OP_D(GetClientRect(rcClient));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 DWORD style = WS_CHILD | WS_VISIBLE;//parent is invisible now
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 if (m_flags & KFlagMultiLine) style |= WS_VSCROLL | ES_MULTILINE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 else style |= ES_AUTOHSCROLL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 if (m_flags & KFlagReadOnly) style |= ES_READONLY;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 if (m_flags & KFlagAlignCenter) style |= ES_CENTER;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 else if (m_flags & KFlagAlignRight) style |= ES_RIGHT;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 else style |= ES_LEFT;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 // ES_NUMBER is buggy in many ways (repaint glitches after balloon popup) and does not allow signed numbers.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 // We implement number handling by filtering WM_CHAR instead.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 // if (m_flags & KFlagNumber) style |= ES_NUMBER;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 CEdit edit;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 WIN32_OP(edit.Create(*this, rcClient, NULL, style, 0, ID_MYEDIT) != NULL);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 edit.SetFont(parent.GetFont());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 if ((m_flags & KFlagDark) != 0) DarkMode::DarkenEditLite(edit);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 if (m_ACData.is_valid()) InitializeSimpleAC(edit, m_ACData.get_ptr(), m_ACOpts);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 m_edit.SubclassWindow(edit);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 m_edit.OnCreation();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 pfc::setWindowText(m_edit, *m_content);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 m_edit.SetSelAll();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 } catch (...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 PostMessage(MSG_COMPLETION, InPlaceEdit::KEditAborted, 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 return m_hWnd;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 ShowWindow(SW_SHOW);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 m_edit.SetFocus();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 m_initialized = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 PFC_ASSERT(m_hWnd != NULL);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 return m_hWnd;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 InPlaceEditContainer(const RECT & p_rect, t_uint32 p_flags, pfc::rcptr_t<pfc::string_base> p_content, reply_t p_notify, IUnknown * ACData, DWORD ACOpts)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 : m_content(p_content), m_notify(p_notify), m_initRect(p_rect),
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 m_flags(p_flags), m_ACData(ACData), m_ACOpts(ACOpts),
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 m_edit(p_flags)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 enum { ID_MYEDIT = 666 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 BEGIN_MSG_MAP_EX(InPlaceEditContainer)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 MESSAGE_HANDLER_EX(WM_CTLCOLOREDIT, MsgForwardToParent)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 MESSAGE_HANDLER_EX(WM_CTLCOLORSTATIC, MsgForwardToParent)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 MESSAGE_HANDLER_EX(WM_MOUSEWHEEL, MsgLostFocus)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 MESSAGE_HANDLER_EX(WM_MOUSEHWHEEL, MsgLostFocus)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 MESSAGE_HANDLER_SIMPLE(MSG_DISABLE_EDITING, OnMsgDisableEditing)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 MESSAGE_HANDLER_EX(MSG_COMPLETION, OnMsgCompletion)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 COMMAND_HANDLER_EX(ID_MYEDIT, EN_CHANGE, OnEditChange)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 MSG_WM_DESTROY(OnDestroy)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 END_MSG_MAP()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 HWND GetEditBox() const { return m_edit; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 void OnDestroy() { m_selfDestruct = true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 LRESULT MsgForwardToParent(UINT msg, WPARAM wParam, LPARAM lParam) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 return GetParent().SendMessage(msg, wParam, lParam);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 LRESULT MsgLostFocus(UINT, WPARAM, LPARAM) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 PostMessage(MSG_COMPLETION, InPlaceEdit::KEditLostFocus, 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 void OnMsgDisableEditing() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 ShowWindow(SW_HIDE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 GetParent().UpdateWindow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 m_disable_editing = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 LRESULT OnMsgCompletion(UINT, WPARAM wParam, LPARAM) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 PFC_ASSERT(m_initialized);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 if ((wParam & KEditMaskReason) != KEditLostFocus) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 GetParent().SetFocus();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 if ( m_changed && m_edit != NULL ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 *m_content = pfc::getWindowText(m_edit);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 OnCompletion((unsigned)wParam);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 if (!m_selfDestruct) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 m_selfDestruct = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 DestroyWindow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 void OnEditChange(UINT, int, CWindow source) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 if (m_initialized && !m_disable_editing) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 *m_content = pfc::getWindowText(source);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 m_changed = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 void OnCompletion(unsigned p_status) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 if (!m_completed) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 m_completed = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 p_status &= KEditMaskReason;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 unsigned code = p_status;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 if (m_changed && p_status != KEditAborted) code |= KEditFlagContentChanged;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 if (m_notify) m_notify(code);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 const pfc::rcptr_t<pfc::string_base> m_content;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 const reply_t m_notify;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400 bool m_completed = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 bool m_initialized = false, m_changed = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 bool m_disable_editing = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 bool m_selfDestruct = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 const CRect m_initRect;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 const t_uint32 m_flags;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 CInPlaceEditBox m_edit;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 const pfc::com_ptr_t<IUnknown> m_ACData;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 const DWORD m_ACOpts;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414 static void fail(reply_t p_notify) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 p_notify(KEditAborted);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 // completion_notify::g_signal_completion_async(p_notify, KEditAborted);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 HWND InPlaceEdit::Start(HWND p_parentwnd, const RECT & p_rect, bool p_multiline, pfc::rcptr_t<pfc::string_base> p_content, reply_t p_notify) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 return StartEx(p_parentwnd, p_rect, p_multiline ? KFlagMultiLine : 0, p_content, p_notify);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 void InPlaceEdit::Start_FromListView(HWND p_listview, unsigned p_item, unsigned p_subitem, unsigned p_linecount, pfc::rcptr_t<pfc::string_base> p_content, reply_t p_notify) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 Start_FromListViewEx(p_listview, p_item, p_subitem, p_linecount, 0, p_content, p_notify);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 bool InPlaceEdit::TableEditAdvance_ListView(HWND p_listview, unsigned p_column_base, unsigned & p_item, unsigned & p_column, unsigned p_item_count, unsigned p_column_count, unsigned p_whathappened) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 if (p_column >= p_column_count) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 pfc::array_t<t_size> orderRev;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 pfc::array_t<unsigned> order;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434 const unsigned orderExCount = /*p_column_base + p_column_count*/ ListView_GetColumnCount(p_listview);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435 PFC_ASSERT(orderExCount >= p_column_base + p_column_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436 pfc::array_t<int> orderEx; orderEx.set_size(orderExCount);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 if (!ListView_GetColumnOrderArray(p_listview, orderExCount, orderEx.get_ptr())) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438 PFC_ASSERT(!"Should not get here - probably mis-calculated column count");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441 order.set_size(p_column_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442 for (unsigned walk = 0; walk < p_column_count; ++walk) order[walk] = orderEx[p_column_base + walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444 orderRev.set_size(p_column_count); order_helper::g_fill(orderRev);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 pfc::sort_get_permutation_t(order, pfc::compare_t<unsigned, unsigned>, p_column_count, orderRev.get_ptr());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448 unsigned columnVisible = (unsigned)orderRev[p_column];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451 if (!TableEditAdvance(p_item, columnVisible, p_item_count, p_column_count, p_whathappened)) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453 p_column = (unsigned)order_helper::g_find_reverse(orderRev.get_ptr(), columnVisible);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 bool InPlaceEdit::TableEditAdvance(unsigned & p_item, unsigned & p_column, unsigned p_item_count, unsigned p_column_count, unsigned p_whathappened) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 if (p_item >= p_item_count || p_column >= p_column_count) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460 int delta = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462 switch (p_whathappened & KEditMaskReason) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463 case KEditEnter:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464 delta = (int)p_column_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466 case KEditTab:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
467 delta = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
468 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
469 case KEditShiftTab:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
470 delta = -1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 while (delta > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476 p_column++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 if (p_column >= p_column_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478 p_column = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 p_item++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480 if (p_item >= p_item_count) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482 delta--;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 while (delta < 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 if (p_column == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486 if (p_item == 0) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487 p_item--;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488 p_column = p_column_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490 p_column--;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 delta++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 HWND InPlaceEdit::StartEx(HWND p_parentwnd, const RECT & p_rect, unsigned p_flags, pfc::rcptr_t<pfc::string_base> p_content, reply_t p_notify, IUnknown * ACData, DWORD ACOpts) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
497 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
498 PFC_ASSERT((CWindow(p_parentwnd).GetWindowLong(GWL_STYLE) & WS_CLIPCHILDREN) != 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
499 return (new CWindowCreateAndDelete<InPlaceEditContainer>(p_parentwnd, p_rect, p_flags, p_content, p_notify, ACData, ACOpts))->GetEditBox();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
500 } catch (...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
501 fail(p_notify);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
502 return NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
503 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
504 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
505
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
506 void InPlaceEdit::Start_FromListViewEx(HWND p_listview, unsigned p_item, unsigned p_subitem, unsigned p_linecount, unsigned p_flags, pfc::rcptr_t<pfc::string_base> p_content, reply_t p_notify) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
507 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
508 ListView_EnsureVisible(p_listview, p_item, FALSE);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
509 RECT itemrect;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
510 WIN32_OP_D(ListView_GetSubItemRect(p_listview, p_item, p_subitem, LVIR_LABEL, &itemrect));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
511
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
512 const bool multiline = p_linecount > 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
513 if (multiline) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
514 itemrect.bottom = itemrect.top + (itemrect.bottom - itemrect.top) * p_linecount;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
515 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
516
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
517 StartEx(p_listview, itemrect, p_flags | (multiline ? KFlagMultiLine : 0), p_content, p_notify);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
518 } catch (...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
519 fail(p_notify);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
520 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
521 }