4 #define WM_MOUSEHWHEEL 0x20E 14 MSG_COMPLETION = WM_USER,
20 static HHOOK g_hook = NULL ;
22 static void GAbortEditing(HWND edit,
t_uint32 code) {
23 CWindow parent = ::GetParent(edit);
24 parent.SendMessage(MSG_DISABLE_EDITING);
25 parent.PostMessage(MSG_COMPLETION, code, 0);
28 static void GAbortEditing(
t_uint32 code) {
30 GAbortEditing(*walk, code);
34 static bool IsSamePopup(CWindow wnd1, CWindow wnd2) {
38 static void MouseEventTest(HWND target, CPoint pt,
bool isWheel) {
40 CWindow edit ( *walk );
42 if (target != edit && IsSamePopup(target, edit)) {
45 CWindow target2 = WindowFromPoint(pt);
46 if (target2 != edit && IsSamePopup(target2, edit)) {
55 static LRESULT CALLBACK GMouseProc(
int nCode,WPARAM wParam,LPARAM lParam) {
56 if (nCode == HC_ACTION) {
57 const MOUSEHOOKSTRUCT * mhs =
reinterpret_cast<const MOUSEHOOKSTRUCT *
>(lParam);
59 case WM_NCLBUTTONDOWN:
60 case WM_NCRBUTTONDOWN:
61 case WM_NCMBUTTONDOWN:
62 case WM_NCXBUTTONDOWN:
67 MouseEventTest(mhs->hwnd, mhs->pt,
false);
71 MouseEventTest(mhs->hwnd, mhs->pt,
true);
75 return CallNextHookEx(g_hook,nCode,wParam,lParam);
78 static LRESULT CALLBACK GKeyboardProc(
int code, WPARAM wp, LPARAM lp) {
79 if (code == HC_ACTION && (lp & (1<<31)) == 0) {
94 return CallNextHookEx(g_keyHook,code,wp,lp);
98 static void on_editbox_creation(HWND p_editbox) {
100 g_editboxes.
add(p_editbox);
101 if (g_hook == NULL) {
102 g_hook = SetWindowsHookEx(WH_MOUSE,GMouseProc,NULL,GetCurrentThreadId());
108 static void UnhookHelper(HHOOK & hook) {
110 if (v != NULL) UnhookWindowsHookEx(v);
112 static void on_editbox_destruction(HWND p_editbox) {
116 UnhookHelper(g_hook);
122 CInPlaceEditBox() : m_selfDestruct() {}
123 BEGIN_MSG_MAP_EX(CInPlaceEditBox)
125 MSG_WM_DESTROY(OnDestroy)
126 MSG_WM_GETDLGCODE(OnGetDlgCode)
127 MSG_WM_KILLFOCUS(OnKillFocus)
129 MSG_WM_KEYDOWN(OnChar)
132 m_typableScope.Set(m_hWnd);
133 on_editbox_creation(m_hWnd);
137 m_selfDestruct =
true;
138 m_typableScope.Set(NULL);
139 on_editbox_destruction(m_hWnd);
140 SetMsgHandled(FALSE);
142 int OnCreate(LPCREATESTRUCT lpCreateStruct) {
144 SetMsgHandled(FALSE);
147 UINT OnGetDlgCode(LPMSG lpMsg) {
148 return DLGC_WANTALLKEYS;
150 void OnKillFocus(CWindow wndFocus) {
152 SetMsgHandled(FALSE);
155 void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {
170 SetMsgHandled(FALSE);
173 void ForwardCompletion(
t_uint32 code) {
174 if (IsWindowEnabled()) {
175 CWindow owner = GetParent();
176 owner.SendMessage(MSG_DISABLE_EDITING);
177 owner.PostMessage(MSG_COMPLETION,code,0);
186 class InPlaceEditContainer :
public CWindowImpl<InPlaceEditContainer> {
188 DECLARE_WND_CLASS_EX(_T(
"{54340C80-248C-4b8e-8CD4-D624A8E9377B}"),0,-1);
191 HWND Create(CWindow parent) {
196 WIN32_OP_D(parent.GetClientRect(&client));
197 IntersectRect(&rect_cropped,&client,&m_initRect);
199 const DWORD containerStyle = WS_BORDER|WS_CHILD;
200 AdjustWindowRect(&rect_cropped,containerStyle,FALSE);
204 WIN32_OP( __super::Create(parent,rect_cropped, NULL, containerStyle) != NULL );
208 WIN32_OP_D(GetClientRect(rcClient));
211 DWORD style = WS_CHILD|WS_VISIBLE;
213 else style |= ES_AUTOHSCROLL;
217 else style |= ES_LEFT;
222 WIN32_OP( edit.Create(*
this, rcClient, NULL, style, 0, ID_MYEDIT) != NULL );
223 edit.SetFont(parent.GetFont());
226 m_edit.SubclassWindow(edit);
239 m_initialized =
true;
241 PFC_ASSERT( m_hWnd != NULL );
247 : m_content(p_content), m_notify(p_notify), m_completed(false), m_initialized(false), m_changed(false), m_disable_editing(false), m_initRect(p_rect), m_flags(p_flags), m_selfDestruct(), m_ACData(ACData), m_ACOpts(ACOpts)
251 enum {ID_MYEDIT = 666};
253 BEGIN_MSG_MAP_EX(InPlaceEditContainer)
254 MESSAGE_HANDLER_EX(WM_CTLCOLOREDIT, MsgForwardToParent)
255 MESSAGE_HANDLER_EX(WM_CTLCOLORSTATIC, MsgForwardToParent)
256 MESSAGE_HANDLER_EX(WM_MOUSEWHEEL, MsgLostFocus)
257 MESSAGE_HANDLER_EX(WM_MOUSEHWHEEL, MsgLostFocus)
258 MESSAGE_HANDLER_SIMPLE(MSG_DISABLE_EDITING, OnMsgDisableEditing)
259 MESSAGE_HANDLER_EX(MSG_COMPLETION, OnMsgCompletion)
260 COMMAND_HANDLER_EX(ID_MYEDIT, EN_CHANGE, OnEditChange)
261 MSG_WM_DESTROY(OnDestroy)
264 HWND GetEditBox()
const {
return m_edit;}
267 void OnDestroy() {m_selfDestruct =
true;}
269 LRESULT MsgForwardToParent(UINT msg, WPARAM wParam, LPARAM lParam) {
270 return GetParent().SendMessage(msg, wParam, lParam);
272 LRESULT MsgLostFocus(UINT, WPARAM, LPARAM) {
276 void OnMsgDisableEditing() {
278 GetParent().UpdateWindow();
279 m_disable_editing =
true;
281 LRESULT OnMsgCompletion(UINT, WPARAM wParam, LPARAM lParam) {
282 PFC_ASSERT(m_initialized);
284 GetParent().SetFocus();
286 OnCompletion(wParam);
287 if (!m_selfDestruct) {
288 m_selfDestruct =
true;
293 void OnEditChange(UINT,
int, CWindow source) {
294 if (m_initialized && !m_disable_editing) {
302 void OnCompletion(
unsigned p_status) {
306 unsigned code = p_status;
308 if (m_notify.is_valid()) m_notify->on_completion(code);
315 bool m_initialized, m_changed;
316 bool m_disable_editing;
318 const CRect m_initRect;
320 CInPlaceEditBox m_edit;
323 const DWORD m_ACOpts;
333 return StartEx(p_parentwnd,p_rect,p_multiline ? KFlagMultiLine : 0, p_content,p_notify);
341 if (p_column >= p_column_count)
return false;
348 PFC_ASSERT( orderExCount >= p_column_base + p_column_count );
350 if (!ListView_GetColumnOrderArray(p_listview,orderExCount,orderEx.
get_ptr())) {
351 PFC_ASSERT(!
"Should not get here - probably mis-calculated column count");
355 for(
unsigned walk = 0; walk < p_column_count; ++walk) order[walk] = orderEx[p_column_base + walk];
361 unsigned columnVisible = (unsigned)orderRev[p_column];
364 if (!
TableEditAdvance(p_item,columnVisible,p_item_count,p_column_count,p_whathappened))
return false;
372 if (p_item >= p_item_count || p_column >= p_column_count)
return false;
375 switch(p_whathappened & KEditMaskReason) {
377 delta = (int) p_column_count;
390 if (p_column >= p_column_count) {
393 if (p_item >= p_item_count)
return false;
399 if (p_item == 0)
return false;
401 p_column = p_column_count;
411 PFC_ASSERT( (CWindow(p_parentwnd).GetWindowLong(GWL_STYLE) & WS_CLIPCHILDREN) != 0 );
421 ListView_EnsureVisible(p_listview,p_item,FALSE);
423 WIN32_OP_D( ListView_GetSubItemRect(p_listview,p_item,p_subitem,LVIR_LABEL,&itemrect) );
425 const bool multiline = p_linecount > 1;
427 itemrect.bottom = itemrect.top + (itemrect.bottom - itemrect.top) * p_linecount;
430 StartEx(p_listview,itemrect,p_flags | (multiline ? KFlagMultiLine : 0),p_content,p_notify);
t_storage & add(const t_param &p_item)
static void sort_get_permutation_t(const t_container &p_data, t_compare p_compare, t_size p_count, t_permutation const &p_permutation)
const t_item * get_ptr() const
static void g_signal_completion_async(service_ptr_t< completion_notify > p_notify, unsigned p_code)
Helper. Checks for null ptr and calls on_completion_async when the ptr is not null.
static void g_fill(t_int *p_order, const t_size p_count)
void Start_FromListView(HWND p_listview, unsigned p_item, unsigned p_subitem, unsigned p_linecount, pfc::rcptr_t< pfc::string_base > p_content, completion_notify_ptr p_notify)
BOOL SHARED_EXPORT uGetWindowText(HWND wnd, pfc::string_base &out)
t_type replace_null_t(t_type &p_var)
bool IsKeyPressed(unsigned vk)
static void fail(completion_notify_ptr p_notify)
int ListView_GetColumnCount(HWND listView)
const_iterator first() const
void set_size(t_size p_size)
HWND StartEx(HWND p_parentwnd, const RECT &p_rect, unsigned p_flags, pfc::rcptr_t< pfc::string_base > p_content, completion_notify_ptr p_notify, IUnknown *ACData=NULL, DWORD ACOpts=0)
BOOL SHARED_EXPORT uSetWindowText(HWND wnd, const char *p_text)
bool TableEditAdvance(unsigned &p_item, unsigned &p_column, unsigned p_item_count, unsigned p_column_count, unsigned p_whathappened)
static t_size g_find_reverse(const t_size *order, t_size val)
Insecure - may deadlock or crash on invalid permutation content. In theory faster than walking the pe...
void 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, completion_notify_ptr p_notify)
HRESULT InitializeSimpleAC(HWND edit, IUnknown *vals, DWORD opts)
bool is_main_thread()
Returns true if calling thread is main app thread, false otherwise.
HWND SHARED_EXPORT FindOwningPopup(HWND p_wnd)
bool 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)
HWND Start(HWND p_parentwnd, const RECT &p_rect, bool p_multiline, pfc::rcptr_t< pfc::string_base > p_content, completion_notify_ptr p_notify)
bool remove_item(t_param const &p_item)