root/lang/objective-cplusplus/i3/trunk/src/gui-windows/InputWindowPlatform.cpp @ 34027

Revision 34027, 16.2 kB (checked in by saturday06, 4 years ago)

owata.....orz

Line 
1#include <PrecompiledHeaders.h>
2#include "Mediator.h"
3#include "InputWindowPlatform.h"
4#include "InputWindow.h"
5
6const int ICON_SIZE = 16;
7
8namespace i3
9{
10using namespace mil;
11
12int touch_x = 0;
13int touch_y = 0;
14bool cap = false;
15
16struct ExecuteEvent
17{
18    HWND hEdit;
19};
20
21template <>
22void Delegate::execute(ExecuteEvent& e)
23{
24    /*
25    TCHAR cwd_buf[MAX_PATH] = {};
26    TCHAR* cwd = cwd_buf;
27    DWORD required = GetCurrentDirectory(_countof(cwd_buf), cwd_buf);
28    if (!required) {
29        return; // error
30    } else if (required > _countof(cwd_buf)) {
31        const size_t BUFFER_CHARS = 33000;
32        cwd = (TCHAR*)malloc(BUFFER_CHARS * sizeof(TCHAR));
33        if (!cwd) {
34            return; // error
35        }
36        if (!GetCurrentDirectory(BUFFER_CHARS, cwd)) {
37            free(cwd);
38            return; // error
39        }
40    }
41
42    TCHAR prog[200] = {};
43    GetWindowText(e.hEdit, prog, _countof(prog));
44
45    HINSTANCE ins = ShellExecute(
46        NULL,       // �e�E�B���h�E�̃n���h��
47        _T("open"),       // ����        prog,       // �����ۂ̃t�@�C��
48        NULL,     // �����p�����[�^
49        cwd,      // ���f�B���N�g��
50        SW_SHOW    // �\����
51        );
52
53    if (cwd != cwd_buf) {
54        free(cwd);
55    }               
56    if ((INT)ins <= 32) {
57        alert(_T("failure"));
58    }
59    */
60}
61
62struct LazyEditFocusEvent {};
63
64template <>
65void InputWindow::execute(LazyEditFocusEvent&)
66{
67    SetFocus(hEdit);
68}
69
70struct EditChangedEvent
71{
72    HWND hEdit;
73};
74
75template <>
76void Delegate::execute(EditChangedEvent& e)
77{
78    //MessageBox(NULL, data, data, MB_OK);
79    HICON new_icon = NULL;
80
81    TCHAR data[MAX_PATH] = {};
82    int result = GetWindowText(e.hEdit, data, _countof(data));
83    if (result)
84    {
85        SHFILEINFO sfi = {};
86        DWORD_PTR dwptr = SHGetFileInfo(data, 0, &sfi,
87            sizeof(sfi), SHGFI_ICON | SHGFI_SMALLICON /* | SHGFI_ADDOVERLAYS */ );
88
89        if (dwptr) // ok
90        {
91            new_icon = sfi.hIcon;
92        }
93    }
94
95    BOOST_STATIC_ASSERT(sizeof(HICON) == sizeof(DWORD_PTR));
96    HICON old = mediator.getInputWindow().hSharedIcon.exchange(new_icon);
97    if (old)
98    {
99        DestroyIcon(old);
100    }
101    HWND hWnd = mediator.getInputWindow().getWindow();
102    RECT r = {0, 0, 20, 20};
103    InvalidateRect(hWnd, &r, TRUE);
104    UpdateWindow(hWnd);
105}
106
107template <>
108InputWindowPlatform<InputWindow>::InputWindowPlatform(Mediator& mediator) :
109    mediator(mediator),
110    hSharedEdit(NULL),
111    hSharedIcon(NULL),
112    hEdit(NULL),
113    riched20_dll(NULL)
114{
115    memset((void*)&layout, 0, sizeof(layout));
116    memset((void*)&ce, 0, sizeof(ce));
117    layout.icon_edit_space = 1;
118    icon = LoadIcon(i3::hInstance, _T("IDI_ICON1"));
119}
120
121template <>
122UINT InputWindowPlatform<InputWindow>::OnNCHitTest(HWND hwnd, int x, int y)
123{
124    return HTCAPTION;
125}
126
127
128template <>
129void InputWindowPlatform<InputWindow>::OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
130{
131#ifdef _WIN32_WCE
132    {
133        SetCapture(hwnd);
134        RECT rect;
135        GetWindowRect(hwnd, &rect);
136        ce.is_capturing = 1;
137        POINT point;
138        point.x = x;
139        point.y = y;
140        ClientToScreen(hwnd, &point);
141        ce.capture_x = point.x - rect.left;
142        ce.capture_y = point.y - rect.top;
143    }
144#endif
145    SetMsgHandled(false);
146}
147
148template <>
149void InputWindowPlatform<InputWindow>::OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
150{
151#ifdef _WIN32_WCE
152    if (ce.is_capturing) {
153        POINT point;
154        point.x = x;
155        point.y = y;
156        ClientToScreen(hwnd, &point);
157        SetWindowPos(hwnd, 0,
158            point.x - ce.capture_x,  point.y - ce.capture_y,
159                        0, 0,
160                        SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOSIZE);
161        SetMsgHandled(true);
162    }
163#endif
164    SetMsgHandled(false);
165}
166
167template <>
168void InputWindowPlatform<InputWindow>::OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
169{
170#ifdef _WIN32_WCE
171    {
172        ReleaseCapture();
173        ce.is_capturing = 0;
174    }
175#endif
176    SetFocus(hEdit);
177    SetMsgHandled(false);
178}
179
180template <>
181HBRUSH InputWindowPlatform<InputWindow>::OnCtlColorEdit(HWND hwnd, HDC hdc, HWND hwndChild, int type)
182{
183    SetMsgHandled(false);
184    return 0;
185}
186
187template <>
188void InputWindowPlatform<InputWindow>::OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized)
189{
190    if (state == WA_INACTIVE) {
191    } else {
192        post(LazyEditFocusEvent(), *this);
193    }
194    SetMsgHandled(false);
195}
196
197template <>
198void InputWindowPlatform<InputWindow>::OnActivateApp(HWND hwnd, BOOL fActivate, DWORD dwThreadId)
199{
200    SetMsgHandled(false);
201}
202
203template <>
204InputWindowPlatform<InputWindow>::~InputWindowPlatform()
205{
206    using namespace std;
207
208    if (!riched20_dll) {
209        return;
210    }
211
212    if (!hEdit || !IsWindow(hEdit)) {
213        return;
214    }
215
216    DestroyWindow(hEdit);
217    FreeLibrary(riched20_dll);
218}
219
220template <>
221void InputWindowPlatform<InputWindow>::OnClose(HWND hwnd)
222{
223    if (hEdit && IsWindow(hEdit)) {
224        TCHAR data[100] = {};
225        GetWindowText(hEdit, data, _countof(data));
226        MessageBox(NULL, data, data, MB_OK);
227        DestroyWindow(hEdit);
228        hEdit = NULL;
229    }
230    destroy();
231}
232
233template <>
234void InputWindowPlatform<InputWindow>::OnDestroy(HWND hwnd)
235{
236    if (IsWindow(hEdit)) {
237        DebugBreak();
238        DestroyWindow(hEdit);
239        hEdit = NULL;
240    }
241    PostQuitMessage(0);
242}
243
244template <>
245void InputWindowPlatform<InputWindow>::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
246{
247    if (hwndCtl == hEdit)
248    {
249        switch (codeNotify)
250        {
251        case EN_CHANGE:
252            {
253                EditChangedEvent e = {hEdit};
254                mediator.getDelegate().post(e, *this);
255            }
256            break;
257        }
258    }
259    SetMsgHandled(false);
260}
261
262
263template <>
264void InputWindowPlatform<InputWindow>::OnKeyDown(HWND hwnd, UINT vk, BOOL fDown, int cRepeat, UINT flags)
265{
266    if (vk == VK_ESCAPE) {
267        PostMessage(getWindow(), WM_CLOSE, 0, 0);
268    }
269}
270
271template <>
272void InputWindowPlatform<InputWindow>::OnNotify(HWND hwnd, int idCtrl, LPNMHDR pnmh) {
273    if (pnmh->hwndFrom != hEdit) {
274        SetMsgHandled(false);
275        return;
276    }
277    switch (pnmh->code)
278    {
279#ifndef _WIN32_WCE
280    case EN_MSGFILTER:
281        {
282            MSGFILTER* filter = reinterpret_cast<MSGFILTER*>(pnmh);
283            if (filter->msg == WM_KEYDOWN) {
284                if (filter->wParam == VK_ESCAPE) {
285                    PostMessage(getWindow(), WM_CLOSE, 0, 0);
286                } else if (filter->wParam == VK_RETURN) {
287                    ExecuteEvent e;
288                    e.hEdit = hEdit;
289                    mediator.getDelegate().post(e, *this);
290                }
291            }
292        }
293        break;
294#endif
295    default:
296        SetMsgHandled(false);
297        break;
298    }
299}
300
301template <>
302void InputWindowPlatform<InputWindow>::OnPaint(HWND hwnd)
303{
304    PAINTSTRUCT ps = {};
305    HDC hdc = BeginPaint(hwnd , &ps);
306
307    if (dll.have_dwmapi_dll) {
308        FillRect(ps.hdc, &ps.rcPaint, (HBRUSH)GetStockObject(BLACK_BRUSH));
309    }
310
311    //HBRUSH hBrushYellow = NULL;
312    //HBRUSH hOldBrush = NULL;
313    //hBrushYellow= CreateSolidBrush(RGB(255,255,0));
314    //hOldBrush= (HBRUSH)SelectObject(hdc,hBrushYellow);  // �u���V���   //Rectangle(hdc, 2, 2, 18, 18);
315    //SelectObject(hdc,hOldBrush);                        // �u���V���
316    //DeleteObject(hBrushYellow);                         // �u���V���
317
318    HICON hMyIcon = hSharedIcon.load();
319    if (!hMyIcon) {
320        TCHAR data[MAX_PATH] = {};
321        int result = GetWindowText(hEdit, data, _countof(data));
322        if (!result)
323        {
324            hMyIcon = icon;
325        }
326    }
327    //DrawIcon(hdc , 2 , 2 , hMyIcon);
328    //DrawIconEx (hdc, 2, 2, hMyIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
329    if (hMyIcon) {
330        int left = ((layout.edit_left - layout.icon_edit_space) - ICON_SIZE) / 2;
331        int top = (layout.nc_height - ICON_SIZE) / 2 - /* XXX margin ?? */ 1;
332        DrawIconEx(hdc, left, top, hMyIcon, ICON_SIZE, ICON_SIZE, 0, NULL, DI_NORMAL /*| DI_COMPAT*/);
333    }
334    EndPaint(hwnd, &ps);
335    SetMsgHandled(false);
336}
337
338template <>
339void InputWindowPlatform<InputWindow>::createUI()
340{
341    if (getWindow()) {
342        return;
343    }
344
345    const int DEFAULT_WINDOW_WIDTH = 200;
346    const int DEFAULT_WINDOW_HEIGHT = 200;
347
348    TCHAR ClassName[] = _T("i3 InputWindow"); //  <- rule required
349    int nCmdShow = SW_SHOW;
350
351    WNDCLASS wc    = {};
352    wc.style         = CS_HREDRAW | CS_VREDRAW;
353    wc.lpfnWndProc   = DefWindowProc;
354    wc.cbClsExtra    = 0;
355    wc.cbWndExtra    = 0;
356    wc.hInstance     = i3::hInstance;
357    wc.hIcon         = NULL;//LoadIcon(hCrtInst, MAKEINTRESOURCE(IDI_ICON1));
358    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
359    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
360    wc.lpszMenuName  = NULL;
361    wc.lpszClassName = ClassName;
362
363    if (!RegisterClass(&wc))
364    {
365        // what ..?
366        debug << wc.lpszClassName;
367        //return;
368    }
369
370    DWORD dwDefaultStyle = /*WS_THICKFRAME*/ WS_BORDER | WS_POPUP;
371
372    HWND w = CreateWindowEx(
373                    0,
374                    ClassName,
375                    _T("i3 Title: InputWindow"), //  <- need rule
376                    dwDefaultStyle,
377                    30, //CW_USEDEFAULT,
378                    30, //CW_USEDEFAULT,
379                    DEFAULT_WINDOW_WIDTH,
380                    DEFAULT_WINDOW_HEIGHT,
381                    NULL,
382                    NULL,
383                    i3::hInstance,
384                    NULL
385                );
386
387    if (!IsWindow(w))
388    {
389        // what ..?
390        halt << w;
391        return;
392    }
393
394    int richedit_style = WS_CHILD | WS_VISIBLE;
395    if (!dll.dll_DwmExtendFrameIntoClientArea) {
396        richedit_style |= WS_BORDER;
397    }
398
399#ifndef _WIN32_WCE
400    TCHAR name[100] = MSFTEDIT_CLASS;
401    HMODULE module = LoadLibrary(_T("Msftedit.dll"));
402    if (!module) {
403        module = LoadLibrary(_T("Riched20.dll"));
404        if (module) {
405            _tcscpy_s(name, RICHEDIT_CLASS);
406        } else {
407            _tcscpy_s(name, _T("EDIT"));
408        }
409    }
410#else
411    TCHAR name[100] = _T("EDIT");
412#endif
413
414    hEdit = CreateWindowEx(
415                0,
416                name,
417                //_T("RICHEDIT"),
418                //_T("EDIT"),
419                _T(""),
420                richedit_style,
421                0,
422                0,
423                100,
424                100,
425                w,
426                NULL,//reinterpret_cast<HMENU>(IDC_EDIT),
427                i3::hInstance,
428                NULL
429            );
430    hSharedEdit.store(hEdit);
431
432    HFONT font = NULL;
433#ifndef _WIN32_WCE
434    // �t�H���g��肷��    NONCLIENTMETRICS NCMetrics = {};
435    NCMetrics.cbSize = sizeof(NCMetrics);
436    if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NCMetrics, 0 ))
437    {
438        font = CreateFontIndirect(&NCMetrics.lfMessageFont);
439    }
440    layout.icon_edit_space = NCMetrics.iBorderWidth;
441    if (!font) {
442        font = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
443    }
444    SendMessage(hEdit, WM_SETFONT, (WPARAM)font, (LPARAM)FALSE);
445
446    // �E�B���h�E�T�C�Y�̍Đݒ�    int cyborder = GetSystemMetrics(SM_CYBORDER);
447    int cysizeframe = GetSystemMetrics(SM_CYSIZEFRAME);
448    int cyfixedframe = GetSystemMetrics(SM_CYFIXEDFRAME);
449    int cyedge = GetSystemMetrics(SM_CYEDGE);
450
451        debug << boost::basic_format<char>(
452                "SM_CYBORDER: %d\n"
453                "SM_CYSIZEFRAME: %d\n"
454                "SM_CYFIXEDFRAME: %d\n"
455                "SM_CYEDGE: %d\n"
456                "NONCLIENTMETRICS::iBorderWidth: %d\n"
457//              "NONCLIENTMETRICS::iPaddedBorderWidth: %d\n"
458                "TEXTMETRIC::tmHeight: %d\n"
459                "TEXTMETRIC::tmExternalLeading: %d\n"
460                )
461                % cyborder % cysizeframe % cyfixedframe % cyedge % NCMetrics.iBorderWidth
462        //% NCMetrics.iPaddedBorderWidth
463                % tm.tmHeight % tm.tmExternalLeading
464                ;
465    if (richedit_style & WS_BORDER) {
466        layout.edit_height += cyedge * 2;
467        layout.edit_height += 3; // top, bottom padding
468        layout.edit_height += 1; // user bottom padding
469    }
470
471    LRESULT dwEvent = SendMessage(hEdit, EM_GETEVENTMASK, 0, 0);
472    dwEvent |= ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE;
473    SendMessage(hEdit, EM_SETEVENTMASK, 0, (LPARAM)dwEvent);
474#else
475    font = (HFONT)SendMessage(hEdit, WM_GETFONT, NULL, NULL);
476    if (!font) {
477        font = (HFONT)GetStockObject(SYSTEM_FONT);
478    }
479#endif
480    // �t�H���g���擾
481    TEXTMETRIC tm = {};
482    {
483        HDC dc = GetDC(w);
484        HFONT old_font = (HFONT)SelectObject(dc, font);
485        GetTextMetrics(dc, &tm);
486        SelectObject(dc, old_font);
487        int result = ReleaseDC(w, dc);
488    }
489    layout.edit_height = tm.tmHeight + tm.tmExternalLeading;
490
491        if (layout.edit_height > ICON_SIZE) {
492                layout.nc_height = layout.edit_height;
493                layout.edit_left = layout.icon_edit_space + layout.edit_height;
494        } else {
495                layout.nc_height = ICON_SIZE;
496                layout.edit_left = layout.icon_edit_space + ICON_SIZE;
497        }
498       
499        {
500                layout.nc_width = 250;
501                DWORD dwStyle = (DWORD)GetWindowLongPtr(w, GWL_STYLE);
502                DWORD dwExStyle = (DWORD)GetWindowLongPtr(w, GWL_EXSTYLE);
503                RECT r;
504                r.top = 0;
505                r.left = 0;
506                r.right = layout.nc_width;
507                r.bottom = layout.nc_height;
508                BOOL b = AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle);
509                if (!b) {
510                        halt << "AdjustWindowRectEx() failed";
511                }
512                SetWindowPos(w, 0,
513                        r.left, r.top,
514                        r.right - r.left, r.bottom - r.top,
515                        SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
516                SetWindowPos(hEdit, 0,
517                        layout.edit_left, (layout.nc_height - layout.edit_height) / 2,
518                        layout.nc_width - layout.edit_left, layout.nc_height,
519                        SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOOWNERZORDER | SWP_NOZORDER);
520        }
521
522    setWindow(w);
523    wndproc.set(w);
524
525    // f
526    if (dll.have_dwmapi_dll) {
527        BOOL enabled = FALSE;
528        HRESULT hr = dll.dll_DwmIsCompositionEnabled(&enabled);
529        if (SUCCEEDED(hr) && enabled) {
530            HRESULT hr = S_OK;
531
532            DWM_BLURBEHIND bb = {};
533            bb.dwFlags = DWM_BB_ENABLE;
534            bb.fEnable = true;
535            hr = dll.dll_DwmEnableBlurBehindWindow(w, &bb);
536
537            DWORD color = 0;
538            BOOL blend = FALSE;
539            if (SUCCEEDED(hr))
540            {
541                hr = dll.dll_DwmGetColorizationColor(&color, &blend);
542                if (SUCCEEDED(hr))
543                {
544                    BYTE a = (color & 0xFF000000) >> 24;
545                    BYTE r = (color & 0x00FF0000) >> 16;
546                    BYTE g = (color & 0x0000FF00) >>  8;
547                    BYTE b = (color & 0x000000FF);
548
549                    //a = 255 - ((255 - a) * 0.3);
550                    a = 0x80;
551                    r = 255;
552                    g = 255;
553                    b = 0;
554                    //r = 255 - ((255 - r) * 0.5);
555                    //g = 255 - ((255 - g) * 0.5);
556                    //b = 255 - ((255 - b) * 0.5);
557
558                    DWORD color2 = (a << 24) | (b << 16) | (g << 8) | r ;
559                    //SendMessage(hEdit, EM_SETBKGNDCOLOR, (WPARAM)0, (LPARAM)(color2));
560                    //printf("");
561                }
562            }
563        }
564        MARGINS margins = {layout.edit_left, 0, 0, 0};
565        hr = dll.dll_DwmExtendFrameIntoClientArea(w,&margins);
566    }
567
568    //InvalidateRect(w, NULL, FALSE);
569    UpdateWindow(w);
570    ShowWindow(w, nCmdShow);
571    //UpdateWindow(hEdit);
572    SetFocus(hEdit);
573
574
575    // -------------------------------------------------------------
576    // lazy init
577    //SetLayeredWindowAttributes(w, 0, 200, LWA_ALPHA);
578
579    // �^�X�N�g���C�p�̃A�C�R���̍쐬
580    NOTIFYICONDATA connectingIcon = {};
581        connectingIcon.cbSize = sizeof(connectingIcon);
582    connectingIcon.hIcon = icon;
583    connectingIcon.hWnd = w;
584    connectingIcon.uCallbackMessage = WM_USER + 10;
585    connectingIcon.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
586    //_tcscpy_s(connectingIcon.szTip, _T(""));
587    _tcscpy_s(connectingIcon.szTip, _T(""));
588    Shell_NotifyIcon(NIM_ADD, &connectingIcon);
589}
590
591}
Note: See TracBrowser for help on using the browser.