Began implementing Area.OpenTextFieldAt() on Windows.

This commit is contained in:
Pietro Gagliardi 2014-08-22 13:57:32 -04:00
parent 93b1d3428a
commit c7268f8fee
4 changed files with 68 additions and 2 deletions

View File

@ -438,3 +438,37 @@ HWND newArea(void *data)
xpanic("container creation failed", GetLastError());
return hwnd;
}
static LRESULT CALLBACK areaTextFieldSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR data)
{
switch (uMsg) {
case WM_KILLFOCUS:
ShowWindow(hwnd, SW_HIDE);
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
case WM_NCDESTROY:
if ((*fv_RemoveWindowSubclass)(hwnd, areaTextFieldSubProc, id) == FALSE)
xpanic("error removing Area TextField subclass (which was for handling WM_KILLFOCUS)", GetLastError());
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
default:
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
}
xmissedmsg("Area TextField", "areaTextFieldSubProc()", uMsg);
return 0; // unreached
}
HWND newAreaTextField(HWND area)
{
HWND tf;
tf = CreateWindowExW(textfieldExtStyle | WS_EX_TOOLWINDOW,
L"edit", L"",
textfieldStyle | WS_POPUP,
0, 0, 0, 0,
area, // owner window
NULL, hInstance, NULL);
if (tf == NULL)
xpanic("error making Area TextField", GetLastError());
if ((*fv_SetWindowSubclass)(tf, areaTextFieldSubProc, 0, (DWORD_PTR) NULL) == FALSE)
xpanic("error subclassing Area TextField to give it its own WM_KILLFOCUS handler", GetLastError());
return tf;
}

View File

@ -18,6 +18,8 @@ type area struct {
_hwnd C.HWND
clickCounter *clickCounter
textfield C.HWND
}
func makeAreaWindowClass() error {
@ -37,6 +39,8 @@ func newArea(ab *areabase) Area {
}
a._hwnd = C.newArea(unsafe.Pointer(a))
a.SetSize(a.width, a.height)
a.textfield = C.newAreaTextField(a._hwnd)
C.controlSetControlFont(a.textfield)
return a
}
@ -67,6 +71,31 @@ func (a *area) RepaintAll() {
C.SendMessageW(a._hwnd, C.msgAreaRepaintAll, 0, 0)
}
// TODO somehow use textfield.preferredSIze() here
func (a *area) OpenTextFieldAt(x, y int) {
if x < 0 || x >= a.width || y < 0 || y >= a.height {
panic(fmt.Errorf("point (%d,%d) outside Area in Area.OpenTextFieldAt()", x, y))
}
C.moveWindow(a.textfield, C.int(x), C.int(y), C.int(200), C.int(20))
C.ShowWindow(a.textfield, C.SW_SHOW)
// TODO SetFocus
}
func (a *area) TextFieldText() string {
return getWindowText(a.textfield)
}
func (a *area) SetTextFieldText(text string) {
t := toUTF16(text)
C.setWindowText(a.textfield, t)
// TODO
// c.settextlen(C.controlTextLength(hwnd, t))
}
func (a *area) OnTextFieldDismissed(f func()) {
// TODO
}
//export doPaint
func doPaint(xrect *C.RECT, hscroll C.int, vscroll C.int, data unsafe.Pointer, dx *C.intptr_t, dy *C.intptr_t) unsafe.Pointer {
a := (*area)(data)

View File

@ -19,8 +19,8 @@ var editclass = toUTF16("EDIT")
func startNewTextField(style C.DWORD) *textfield {
hwnd := C.newControl(editclass,
style | C.ES_AUTOHSCROLL | C.ES_LEFT | C.ES_NOHIDESEL | C.WS_TABSTOP,
C.WS_EX_CLIENTEDGE) // WS_EX_CLIENTEDGE without WS_BORDER will show the canonical visual styles border (thanks to MindChild in irc.efnet.net/#winprog)
style | C.textfieldStyle,
C.textfieldExtStyle) // WS_EX_CLIENTEDGE without WS_BORDER will show the canonical visual styles border (thanks to MindChild in irc.efnet.net/#winprog)
t := &textfield{
_hwnd: hwnd,
changed: newEvent(),

View File

@ -67,6 +67,8 @@ extern void setButtonSubclass(HWND, void *);
extern void setCheckboxSubclass(HWND, void *);
extern BOOL checkboxChecked(HWND);
extern void checkboxSetChecked(HWND, BOOL);
#define textfieldStyle (ES_AUTOHSCROLL | ES_LEFT | ES_NOHIDESEL | WS_TABSTOP)
#define textfieldExtStyle (WS_EX_CLIENTEDGE)
extern void setTextFieldSubclass(HWND, void *);
extern void textfieldSetAndShowInvalidBalloonTip(HWND, WCHAR *);
extern void textfieldHideInvalidBalloonTip(HWND);
@ -127,6 +129,7 @@ extern void calculateBaseUnits(HWND, int *, int *, LONG *);
extern void repaintArea(HWND, RECT *);
extern DWORD makeAreaWindowClass(char **);
extern HWND newArea(void *);
extern HWND newAreaTextField(HWND);
// imagelist_windows.c
extern HBITMAP unscaledBitmap(void *, intptr_t, intptr_t);