Migrated all the single-HWND controls that don't have a child. Moment of truth time: do we require all controls to have a single HWND? Leaning toward yes.

This commit is contained in:
Pietro Gagliardi 2015-08-30 12:25:53 -04:00
parent d4bb41f4c0
commit 465d497cb6
12 changed files with 360 additions and 500 deletions

View File

@ -8,7 +8,7 @@ struct uiButton {
void *onClickedData;
};
uiDarwinDefineControlWithOnDestroy(
uiWindowsDefineControlWithOnDestroy(
uiButton, // type name
uiButtonType, // type function
uiWindowsUnregisterWM_COMMANDHandler(this->hwnd); // on destroy

108
redo/windows/checkbox.c Normal file
View File

@ -0,0 +1,108 @@
// 7 april 2015
#include "uipriv_windows.h"
struct uiCheckbox {
uiWindowsControl c;
HWND hwnd;
void (*onToggled)(uiCheckbox *, void *);
void *onToggledData;
};
uiWindowsDefineControlWithOnDestroy(
uiCheckbox, // type name
uiCheckboxType, // type function
uiWindowsUnregisterWM_COMMANDHandler(this->hwnd); // on destroy
)
static BOOL onWM_COMMAND(uiControl *cc, HWND hwnd, WORD code, LRESULT *lResult)
{
uiCheckbox *c = uiCheckbox(cc);
WPARAM check;
if (code != BN_CLICKED)
return FALSE;
// we didn't use BS_AUTOCHECKBOX (TODO get link) so we have to manage the check state ourselves
check = BST_CHECKED;
if (SendMessage(c->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED)
check = BST_UNCHECKED;
SendMessage(c->hwnd, BM_SETCHECK, check, 0);
(*(c->onToggled))(c, c->onToggledData);
*lResult = 0;
return TRUE;
}
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define checkboxHeight 10
// from http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx
#define checkboxXFromLeftOfBoxToLeftOfLabel 12
static void minimumSize(uiControl *cc, uiWindowsSizing *d, intmax_t *width, intmax_t *height)
{
uiCheckbox *c = uiCheckbox(cc);
*width = uiWindowsDlgUnitsToX(checkboxXFromLeftOfBoxToLeftOfLabel, d->BaseX) + uiWindowsWindowTextWidth(c->hwnd);
*height = uiWindowsDlgUnitsToY(checkboxHeight, d->BaseY);
}
static void defaultOnToggled(uiCheckbox *c, void *data)
{
// do nothing
}
char *uiCheckboxText(uiCheckbox *c)
{
return uiWindowsUtilText(c->hwnd);
}
void uiCheckboxSetText(uiCheckbox *c, const char *text)
{
uiWindowsUtilSetText(c->hwnd, text);
// changing the text might necessitate a change in the checkbox's size
uiControlQueueResize(uiControl(c));
}
void uiCheckboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *, void *), void *data)
{
c->onToggled = f;
c->onToggledData = data;
}
int uiCheckboxChecked(uiCheckbox *c)
{
return SendMessage(c->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED;
}
void uiCheckboxSetChecked(uiCheckbox *c, int checked)
{
WPARAM check;
check = BST_CHECKED;
if (!checked)
check = BST_UNCHECKED;
SendMessage(c->hwnd, BM_SETCHECK, check, 0);
}
uiCheckbox *uiNewCheckbox(const char *text)
{
uiCheckbox *c;
WCHAR *wtext;
c = (uiCheckbox *) uiNewControl(uiCheckboxType());
wtext = toUTF16(text);
c->hwnd = uiWindowsEnsureCreateControlHWND(0,
L"button", wtext,
BS_CHECKBOX | WS_TABSTOP,
hInstance, NULL,
TRUE);
uiFree(wtext);
uiWindowsRegisterWM_COMMANDHandler(c->hwnd, onWM_COMMAND, uiControl(c));
uiCheckboxOnToggled(c, defaultOnToggled, NULL);
uiWindowsFinishNewControl(c, uiCheckbox);
return c;
}

View File

@ -3,33 +3,28 @@
// we as Common Controls 6 users don't need to worry about the height of comboboxes; see http://blogs.msdn.com/b/oldnewthing/archive/2006/03/10/548537.aspx
struct combobox {
uiCombobox c;
struct uiCombobox {
uiWindowsControl c;
HWND hwnd;
};
uiDefineControlType(uiCombobox, uiTypeCombobox, struct combobox)
static uintptr_t comboboxHandle(uiControl *cc)
{
struct combobox *c = (struct combobox *) cc;
return (uintptr_t) (c->hwnd);
}
uiWindowsDefineControl(
uiCombobox, // type name
uiComboboxType // type function
)
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define comboboxWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary */
#define comboboxHeight 14
static void comboboxPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
static void minimumSize(uiControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height)
{
*width = uiWindowsDlgUnitsToX(comboboxWidth, d->Sys->BaseX);
*height = uiWindowsDlgUnitsToY(comboboxHeight, d->Sys->BaseY);
*width = uiWindowsDlgUnitsToX(comboboxWidth, d->BaseX);
*height = uiWindowsDlgUnitsToY(comboboxHeight, d->BaseY);
}
static void comboboxAppend(uiCombobox *cc, const char *text)
void uiComboboxAppend(uiCombobox *c, const char *text)
{
struct combobox *c = (struct combobox *) cc;
WCHAR *wtext;
LRESULT res;
@ -44,9 +39,9 @@ static void comboboxAppend(uiCombobox *cc, const char *text)
static uiCombobox *finishNewCombobox(DWORD style)
{
struct combobox *c;
uiCombobox *c;
c = (struct combobox *) uiWindowsNewSingleHWNDControl(uiTypeCombobox());
c = (uiCombobox *) uiNewControl(uiComboboxType());
c->hwnd = uiWindowsUtilCreateControlHWND(WS_EX_CLIENTEDGE,
L"combobox", L"",
@ -54,12 +49,9 @@ static uiCombobox *finishNewCombobox(DWORD style)
hInstance, NULL,
TRUE);
uiControl(c)->Handle = comboboxHandle;
uiControl(c)->PreferredSize = comboboxPreferredSize;
uiWindowsFinishNewControl(c, uiCombobox);
uiCombobox(c)->Append = comboboxAppend;
return uiCombobox(c);
return c;
}
uiCombobox *uiNewCombobox(void)

View File

@ -1,13 +1,16 @@
// 22 may 2015
#include "uipriv_windows.h"
struct datetimepicker {
uiDateTimePicker d;
struct uiDateTimePicker {
uiWindowsControl c;
HWND hwnd;
void (*baseCommitDestroy)(uiControl *);
};
uiDefineControlType(uiDateTimePicker, uiTypeDateTimePicker, struct datetimepicker)
uiWindowsDefineControlWithOnDestroy(
uiDateTimePicker, // type name
uiDateTimePickerType, // type function
uiWindowsUnregisterReceiveWM_WININICHANGE(this->hwnd); // on destroy
)
// utility functions
@ -103,42 +106,27 @@ static void setDateTimeFormat(HWND hwnd)
// control implementation
static void datetimepickerCommitDestroy(uiControl *c)
{
struct datetimepicker *d = (struct datetimepicker *) c;
uiWindowsUnregisterReceiveWM_WININICHANGE(d->hwnd);
(*(d->baseCommitDestroy))(uiControl(d));
}
static uintptr_t datetimepickerHandle(uiControl *c)
{
struct datetimepicker *d = (struct datetimepicker *) c;
return (uintptr_t) (d->hwnd);
}
// the height returned from DTM_GETIDEALSIZE is unreliable; see http://stackoverflow.com/questions/30626549/what-is-the-proper-use-of-dtm-getidealsize-treating-the-returned-size-as-pixels
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define entryHeight 14
static void datetimepickerPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
static void minimumSize(uiControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height)
{
struct datetimepicker *dd = (struct datetimepicker *) c;
uiDateTimePicker *d = uiDateTimePicker(c);
SIZE s;
s.cx = 0;
s.cy = 0;
SendMessageW(dd->hwnd, DTM_GETIDEALSIZE, 0, (LPARAM) (&s));
*width = s.cx;
*height = uiWindowsDlgUnitsToY(entryHeight, d->Sys->BaseY);
*height = uiWindowsDlgUnitsToY(entryHeight, d->BaseY);
}
uiDateTimePicker *finishNewDateTimePicker(DWORD style)
static uiDateTimePicker *finishNewDateTimePicker(DWORD style)
{
struct datetimepicker *d;
uiDateTimePicker *d;
d = (struct datetimepicker *) uiWindowsNewSingleHWNDControl(uiTypeDateTimePicker());
d = (uiDateTimePicker *) uiNewControl(uiDateTimePickerType());
d->hwnd = uiWindowsUtilCreateControlHWND(WS_EX_CLIENTEDGE,
DATETIMEPICK_CLASSW, L"",
@ -151,12 +139,9 @@ uiDateTimePicker *finishNewDateTimePicker(DWORD style)
// for our date/time mode, we do it in a subclass assigned in uiNewDateTimePicker()
uiWindowsRegisterReceiveWM_WININICHANGE(d->hwnd);
d->baseCommitDestroy = uiControl(d)->CommitDestroy;
uiControl(d)->CommitDestroy = datetimepickerCommitDestroy;
uiControl(d)->Handle = datetimepickerHandle;
uiControl(d)->PreferredSize = datetimepickerPreferredSize;
uiWindowsFinishNewControl(d, uiDateTimePicker);
return uiDateTimePicker(d);
return d;
}
static LRESULT CALLBACK datetimepickerSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
@ -178,15 +163,13 @@ static LRESULT CALLBACK datetimepickerSubProc(HWND hwnd, UINT uMsg, WPARAM wPara
uiDateTimePicker *uiNewDateTimePicker(void)
{
uiDateTimePicker *dtp;
struct datetimepicker *d;
uiDateTimePicker *d;
dtp = finishNewDateTimePicker(0);
d = (struct datetimepicker *) dtp;
d = finishNewDateTimePicker(0);
setDateTimeFormat(d->hwnd);
if (SetWindowSubclass(d->hwnd, datetimepickerSubProc, 0, (DWORD_PTR) d) == FALSE)
logLastError("error subclassing date-time-picker to assist in locale change handling in uiNewDateTimePicker()");
return dtp;
return d;
}
uiDateTimePicker *uiNewDatePicker(void)

100
redo/windows/entry.c Normal file
View File

@ -0,0 +1,100 @@
// 8 april 2015
#include "uipriv_windows.h"
struct uiEntry {
uiWindowsControl c;
HWND hwnd;
void (*onChanged)(uiEntry *, void *);
void *onChangedData;
BOOL inhibitChanged;
};
uiWindowsDefineControlWithOnDestroy(
uiEntry, // type name
uiEntryType, // type function
uiWindowsUnregisterWM_COMMANDHandler(this->hwnd); // on destroy
)
static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
{
uiEntry *e = uiEntry(c);
if (code != EN_CHANGE)
return FALSE;
if (e->inhibitChanged)
return FALSE;
(*(e->onChanged))(e, e->onChangedData);
*lResult = 0;
return TRUE;
}
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define entryWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary */
#define entryHeight 14
static void minimumSize(uiControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height)
{
*width = uiWindowsDlgUnitsToX(entryWidth, d->BaseX);
*height = uiWindowsDlgUnitsToY(entryHeight, d->BaseY);
}
static void defaultOnChanged(uiEntry *e, void *data)
{
// do nothing
}
char *uiEntryText(uiEntry *e)
{
return uiWindowsUtilText(e->hwnd);
}
void uiEntrySetText(uiEntry *e, const char *text)
{
// doing this raises an EN_CHANGED
e->inhibitChanged = TRUE;
uiWindowsUtilSetText(e->hwnd, text);
e->inhibitChanged = FALSE;
// don't queue the control for resize; entry sizes are independent of their contents
}
void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data)
{
e->onChanged = f;
e->onChangedData = data;
}
int uiEntryReadOnly(uiEntry *e)
{
return (getStyle(e->hwnd) & ES_READONLY) != 0;
}
void uiEntrySetReadOnly(uiEntry *e, int readonly)
{
WPARAM ro;
ro = (WPARAM) FALSE;
if (readonly)
ro = (WPARAM) TRUE;
if (SendMessage(e->hwnd, EM_SETREADONLY, ro, 0) == 0)
logLastError("error making uiEntry read-only in uiEntrySetReadOnly()");
}
uiEntry *uiNewEntry(void)
{
uiEntry *e;
e = (uiEntry *) uiWindowsNewSingleHWNDControl(uiNewControl());
e->hwnd = uiWindowsUtilCreateControlHWND(WS_EX_CLIENTEDGE,
L"edit", L"",
ES_AUTOHSCROLL | ES_LEFT | ES_NOHIDESEL | WS_TABSTOP,
hInstance, NULL,
TRUE);
uiWindowsRegisterWM_COMMANDHandler(e->hwnd, onWM_COMMAND, uiControl(e));
uiEntrySetOnChanged(e, defaultOnChanged, NULL);
uiWindowsFinishNewControl(e, uiEntry);
return e;
}

View File

@ -1,42 +1,34 @@
// 11 april 2015
#include "uipriv_windows.h"
struct label {
uiLabel l;
struct uiLabel {
uiWindowsControl c;
HWND hwnd;
};
uiDefineControlType(uiLabel, uiTypeLabel, struct label)
static uintptr_t labelHandle(uiControl *c)
{
struct label *l = (struct label *) c;
return (uintptr_t) (l->hwnd);
}
uiWindowsDefineControl(
uiLabel, // type name
uiLabelType // type function
)
// via http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define labelHeight 8
static void labelPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
static void minimumSize(uiControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height)
{
struct label *l = (struct label *) c;
uiLabel *l = uiLabel(c);
*width = uiWindowsWindowTextWidth(l->hwnd);
*height = uiWindowsDlgUnitsToY(labelHeight, d->Sys->BaseY);
*height = uiWindowsDlgUnitsToY(labelHeight, d->BaseY);
}
static char *labelText(uiLabel *ll)
char *uiLabelText(uiLabel *l)
{
struct label *l = (struct label *) ll;
return uiWindowsUtilText(l->hwnd);
}
static void labelSetText(uiLabel *ll, const char *text)
void uiLabelSetText(uiLabel *l, const char *text)
{
struct label *l = (struct label *) ll;
uiWindowsUtilSetText(l->hwnd, text);
// changing the text might necessitate a change in the label's size
uiControlQueueResize(uiControl(l));
@ -44,10 +36,10 @@ static void labelSetText(uiLabel *ll, const char *text)
uiLabel *uiNewLabel(const char *text)
{
struct label *l;
uiLabel *l;
WCHAR *wtext;
l = (struct label *) uiWindowsNewSingleHWNDControl(uiTypeLabel());
l = (uiLabel *) uiNewControl(uiLabelType());
wtext = toUTF16(text);
l->hwnd = uiWindowsUtilCreateControlHWND(0,
@ -59,11 +51,7 @@ uiLabel *uiNewLabel(const char *text)
TRUE);
uiFree(wtext);
uiControl(l)->Handle = labelHandle;
uiControl(l)->PreferredSize = labelPreferredSize;
uiWindowsFinishNewControl(l, uiLabel);
uiLabel(l)->Text = labelText;
uiLabel(l)->SetText = labelSetText;
return uiLabel(l);
return l;
}

View File

@ -1,25 +1,21 @@
// 19 may 2015
#include "uipriv_windows.h"
struct progressbar {
uiProgressBar p;
struct uiProgressBar {
uiWindowsControl c;
HWND hwnd;
};
uiDefineControlType(uiProgressBar, uiTypeProgressBar, struct progressbar)
static uintptr_t progressbarHandle(uiControl *c)
{
struct progressbar *p = (struct progressbar *) c;
return (uintptr_t) (p->hwnd);
}
uiWindowsDefineControl(
uiProgressBar, // type name
uiProgressBarType // type function
)
// via http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define pbarWidth 237
#define pbarHeight 8
static void progressbarPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
static void minimumSize(uiControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height)
{
*width = uiWindowsDlgUnitsToX(pbarWidth, d->Sys->BaseX);
*height = uiWindowsDlgUnitsToY(pbarHeight, d->Sys->BaseY);
@ -29,12 +25,10 @@ static void progressbarPreferredSize(uiControl *c, uiSizing *d, intmax_t *width,
// we have to set the progress bar to value + 1 and decrease it back to value if we want an "instant" change
// see http://stackoverflow.com/questions/2217688/windows-7-aero-theme-progress-bar-bug
// it's not ideal/perfect, but it will have to do
static void progressbarSetValue(uiProgressBar *pp, int value)
void uiProgressBarSetValue(uiProgressBar *p, int value)
{
struct progressbar *p = (struct progressbar *) pp;
if (value < 0 || value > 100)
complain("value %d out of range in progressbarSetValue()", value);
complain("value %d out of range in uiProgressBarSetValue()", value);
if (value == 100) { // because we can't 101
SendMessageW(p->hwnd, PBM_SETRANGE32, 0, 101);
SendMessageW(p->hwnd, PBM_SETPOS, 101, 0);
@ -48,9 +42,9 @@ static void progressbarSetValue(uiProgressBar *pp, int value)
uiProgressBar *uiNewProgressBar(void)
{
struct progressbar *p;
uiProgressBar *p;
p = (struct progressbar *) uiWindowsNewSingleHWNDControl(uiTypeProgressBar());
p = (uiProgressBar *) uiNewControl(uiProgressBarType());
p->hwnd = uiWindowsUtilCreateControlHWND(0,
PROGRESS_CLASSW, L"",
@ -58,10 +52,7 @@ uiProgressBar *uiNewProgressBar(void)
hInstance, NULL,
FALSE);
uiControl(p)->Handle = progressbarHandle;
uiControl(p)->PreferredSize = progressbarPreferredSize;
uiWindowsFinishNewControl(p, uiProgressBar);
uiProgressBar(p)->SetValue = progressbarSetValue;
return uiProgressBar(p);
return p;
}

View File

@ -5,24 +5,20 @@
// - http://stackoverflow.com/questions/2892703/how-do-i-draw-separators
// - https://msdn.microsoft.com/en-us/library/windows/desktop/dn742405%28v=vs.85%29.aspx
struct separator {
uiSeparator s;
struct uiSeparator {
uiWindowsControl c;
HWND hwnd;
};
uiDefineControlType(uiSeparator, uiTypeSeparator, struct separator)
static uintptr_t separatorHandle(uiControl *c)
{
struct separator *s = (struct separator *) c;
return (uintptr_t) (s->hwnd);
}
uiWindowsDefineControl(
uiSeparator, // type name
uiSeparatorType // type function
)
// via https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx
#define separatorHeight 1
static void separatorPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
static void minimumSize(uiControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height)
{
*width = 1; // TODO
*height = uiWindowsDlgUnitsToY(separatorHeight, d->Sys->BaseY);
@ -30,9 +26,9 @@ static void separatorPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, i
uiSeparator *uiNewHorizontalSeparator(void)
{
struct separator *s;
uiSeparator *s;
s = (struct separator *) uiWindowsNewSingleHWNDControl(uiTypeSeparator());
s = (uiSeparator *) uiNewControl(uiSeparatorType());
s->hwnd = uiWindowsUtilCreateControlHWND(0,
L"static", L"",
@ -40,8 +36,7 @@ uiSeparator *uiNewHorizontalSeparator(void)
hInstance, NULL,
TRUE);
uiControl(s)->Handle = separatorHandle;
uiControl(s)->PreferredSize = separatorPreferredSize;
uiWindowsFinishNewControl(s, uiSeparator);
return uiSeparator(s);
return s;
}

80
redo/windows/slider.c Normal file
View File

@ -0,0 +1,80 @@
// 20 may 2015
#include "uipriv_windows.h"
struct uiSlider {
uiWindowsControl c;
HWND hwnd;
void (*onChanged)(uiSlider *, void *);
void *onChangedData;
};
uiWindowsDefineControlWithOnDestroy(
uiSlider, // type name
uiSliderType, // type function
uiWindowsUnregisterWM_HSCROLLHandler(this->hwnd); // on destroy
)
static BOOL onWM_HSCROLL(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
{
uiSlider *s = uiSlider(c);
(*(s->onChanged))(s, s->onChangedData);
*lResult = 0;
return TRUE;
}
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define sliderWidth 107 /* this is actually the shorter progress bar width, but Microsoft doesn't indicate a width */
#define sliderHeight 15
static void minimumSize(uiControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height)
{
*width = uiWindowsDlgUnitsToX(sliderWidth, d->BaseX);
*height = uiWindowsDlgUnitsToY(sliderHeight, d->BaseY);
}
static void defaultOnChanged(uiSlider *s, void *data)
{
// do nothing
}
intmax_t uiSliderValue(uiSlider *s)
{
return (intmax_t) SendMessageW(s->hwnd, TBM_GETPOS, 0, 0);
}
void uiSliderSetValue(uiSlider *s, intmax_t value)
{
// don't use TBM_SETPOSNOTIFY; that triggers an event
SendMessageW(s->hwnd, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) value);
}
void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *, void *), void *data)
{
s->onChanged = f;
s->onChangedData = data;
}
uiSlider *uiNewSlider(intmax_t min, intmax_t max)
{
uiSlider *s;
s = (uiSlider *) uiNewControl(uiSliderType());
s->hwnd = uiWindowsUtilCreateControlHWND(0,
TRACKBAR_CLASSW, L"",
TBS_HORZ | TBS_TOOLTIPS | TBS_TRANSPARENTBKGND | WS_TABSTOP,
hInstance, NULL,
TRUE);
uiWindowsRegisterWM_HSCROLLHandler(s->hwnd, onWM_HSCROLL, uiControl(s));
uiSliderOnChanged(s, defaultOnChanged, NULL);
SendMessageW(s->hwnd, TBM_SETRANGEMIN, (WPARAM) TRUE, (LPARAM) min);
SendMessageW(s->hwnd, TBM_SETRANGEMAX, (WPARAM) TRUE, (LPARAM) max);
SendMessageW(s->hwnd, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) min);
uiWindowsFinishNewControl(s, uiSlider);
return s;
}

View File

@ -1,139 +0,0 @@
// 7 april 2015
#include "uipriv_windows.h"
struct checkbox {
uiCheckbox c;
HWND hwnd;
void (*onToggled)(uiCheckbox *, void *);
void *onToggledData;
void (*baseCommitDestroy)(uiControl *);
};
uiDefineControlType(uiCheckbox, uiTypeCheckbox, struct checkbox)
static BOOL onWM_COMMAND(uiControl *cc, HWND hwnd, WORD code, LRESULT *lResult)
{
struct checkbox *c = (struct checkbox *) cc;
WPARAM check;
if (code != BN_CLICKED)
return FALSE;
// we didn't use BS_AUTOCHECKBOX (see controls_windows.go) so we have to manage the check state ourselves
check = BST_CHECKED;
if (SendMessage(c->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED)
check = BST_UNCHECKED;
SendMessage(c->hwnd, BM_SETCHECK, check, 0);
(*(c->onToggled))(uiCheckbox(c), c->onToggledData);
*lResult = 0;
return TRUE;
}
static void checkboxCommitDestroy(uiControl *cc)
{
struct checkbox *c = (struct checkbox *) cc;
uiWindowsUnregisterWM_COMMANDHandler(c->hwnd);
(*(c->baseCommitDestroy))(uiControl(c));
}
static uintptr_t checkboxHandle(uiControl *cc)
{
struct checkbox *c = (struct checkbox *) cc;
return (uintptr_t) (c->hwnd);
}
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define checkboxHeight 10
// from http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx
#define checkboxXFromLeftOfBoxToLeftOfLabel 12
static void checkboxPreferredSize(uiControl *cc, uiSizing *d, intmax_t *width, intmax_t *height)
{
struct checkbox *c = (struct checkbox *) cc;
*width = uiWindowsDlgUnitsToX(checkboxXFromLeftOfBoxToLeftOfLabel, d->Sys->BaseX) + uiWindowsWindowTextWidth(c->hwnd);
*height = uiWindowsDlgUnitsToY(checkboxHeight, d->Sys->BaseY);
}
static void defaultOnToggled(uiCheckbox *c, void *data)
{
// do nothing
}
static char *checkboxText(uiCheckbox *cc)
{
struct checkbox *c = (struct checkbox *) cc;
return uiWindowsUtilText(c->hwnd);
}
static void checkboxSetText(uiCheckbox *cc, const char *text)
{
struct checkbox *c = (struct checkbox *) cc;
uiWindowsUtilSetText(c->hwnd, text);
// changing the text might necessitate a change in the checkbox's size
uiControlQueueResize(uiControl(c));
}
static void checkboxOnToggled(uiCheckbox *cc, void (*f)(uiCheckbox *, void *), void *data)
{
struct checkbox *c = (struct checkbox *) cc;
c->onToggled = f;
c->onToggledData = data;
}
static int checkboxChecked(uiCheckbox *cc)
{
struct checkbox *c = (struct checkbox *) cc;
return SendMessage(c->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED;
}
static void checkboxSetChecked(uiCheckbox *cc, int checked)
{
struct checkbox *c = (struct checkbox *) cc;
WPARAM check;
check = BST_CHECKED;
if (!checked)
check = BST_UNCHECKED;
SendMessage(c->hwnd, BM_SETCHECK, check, 0);
}
uiCheckbox *uiNewCheckbox(const char *text)
{
struct checkbox *c;
WCHAR *wtext;
c = (struct checkbox *) uiWindowsNewSingleHWNDControl(uiTypeCheckbox());
wtext = toUTF16(text);
c->hwnd = uiWindowsUtilCreateControlHWND(0,
L"button", wtext,
BS_CHECKBOX | WS_TABSTOP,
hInstance, NULL,
TRUE);
uiFree(wtext);
uiWindowsRegisterWM_COMMANDHandler(c->hwnd, onWM_COMMAND, uiControl(c));
c->onToggled = defaultOnToggled;
uiControl(c)->Handle = checkboxHandle;
uiControl(c)->PreferredSize = checkboxPreferredSize;
c->baseCommitDestroy = uiControl(c)->CommitDestroy;
uiControl(c)->CommitDestroy = checkboxCommitDestroy;
uiCheckbox(c)->Text = checkboxText;
uiCheckbox(c)->SetText = checkboxSetText;
uiCheckbox(c)->OnToggled = checkboxOnToggled;
uiCheckbox(c)->Checked = checkboxChecked;
uiCheckbox(c)->SetChecked = checkboxSetChecked;
return uiCheckbox(c);
}

View File

@ -1,131 +0,0 @@
// 8 april 2015
#include "uipriv_windows.h"
struct entry {
uiEntry e;
HWND hwnd;
void (*onChanged)(uiEntry *, void *);
void *onChangedData;
BOOL inhibitChanged;
void (*baseCommitDestroy)(uiControl *);
};
uiDefineControlType(uiEntry, uiTypeEntry, struct entry)
static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
{
struct entry *e = (struct entry *) c;
if (code != EN_CHANGE)
return FALSE;
if (e->inhibitChanged)
return FALSE;
(*(e->onChanged))(uiEntry(e), e->onChangedData);
*lResult = 0;
return TRUE;
}
static void entryCommitDestroy(uiControl *c)
{
struct entry *e = (struct entry *) c;
uiWindowsUnregisterWM_COMMANDHandler(e->hwnd);
(*(e->baseCommitDestroy))(uiControl(e));
}
static uintptr_t entryHandle(uiControl *c)
{
struct entry *e = (struct entry *) c;
return (uintptr_t) (e->hwnd);
}
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define entryWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary */
#define entryHeight 14
static void entryPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
{
*width = uiWindowsDlgUnitsToX(entryWidth, d->Sys->BaseX);
*height = uiWindowsDlgUnitsToY(entryHeight, d->Sys->BaseY);
}
static void defaultOnChanged(uiEntry *e, void *data)
{
// do nothing
}
static char *entryText(uiEntry *ee)
{
struct entry *e = (struct entry *) ee;
return uiWindowsUtilText(e->hwnd);
}
static void entrySetText(uiEntry *ee, const char *text)
{
struct entry *e = (struct entry *) ee;
// doing this raises an EN_CHANGED
e->inhibitChanged = TRUE;
uiWindowsUtilSetText(e->hwnd, text);
e->inhibitChanged = FALSE;
// don't queue the control for resize; entry sizes are independent of their contents
}
static void entryOnChanged(uiEntry *ee, void (*f)(uiEntry *, void *), void *data)
{
struct entry *e = (struct entry *) ee;
e->onChanged = f;
e->onChangedData = data;
}
static int entryReadOnly(uiEntry *ee)
{
struct entry *e = (struct entry *) ee;
return (getStyle(e->hwnd) & ES_READONLY) != 0;
}
static void entrySetReadOnly(uiEntry *ee, int readonly)
{
struct entry *e = (struct entry *) ee;
WPARAM ro;
ro = (WPARAM) FALSE;
if (readonly)
ro = (WPARAM) TRUE;
if (SendMessage(e->hwnd, EM_SETREADONLY, ro, 0) == 0)
logLastError("error making uiEntry read-only in entrySetReadOnly()");
}
uiEntry *uiNewEntry(void)
{
struct entry *e;
e = (struct entry *) uiWindowsNewSingleHWNDControl(uiTypeEntry());
e->hwnd = uiWindowsUtilCreateControlHWND(WS_EX_CLIENTEDGE,
L"edit", L"",
ES_AUTOHSCROLL | ES_LEFT | ES_NOHIDESEL | WS_TABSTOP,
hInstance, NULL,
TRUE);
uiWindowsRegisterWM_COMMANDHandler(e->hwnd, onWM_COMMAND, uiControl(e));
e->onChanged = defaultOnChanged;
uiControl(e)->Handle = entryHandle;
uiControl(e)->PreferredSize = entryPreferredSize;
e->baseCommitDestroy = uiControl(e)->CommitDestroy;
uiControl(e)->CommitDestroy = entryCommitDestroy;
uiEntry(e)->Text = entryText;
uiEntry(e)->SetText = entrySetText;
uiEntry(e)->OnChanged = entryOnChanged;
uiEntry(e)->ReadOnly = entryReadOnly;
uiEntry(e)->SetReadOnly = entrySetReadOnly;
return uiEntry(e);
}

View File

@ -1,107 +0,0 @@
// 20 may 2015
#include "uipriv_windows.h"
struct slider {
uiSlider s;
HWND hwnd;
void (*baseResize)(uiControl *, intmax_t, intmax_t, intmax_t, intmax_t, uiSizing *);
void (*onChanged)(uiSlider *, void *);
void *onChangedData;
void (*baseCommitDestroy)(uiControl *);
};
uiDefineControlType(uiSlider, uiTypeSlider, struct slider)
static BOOL onWM_HSCROLL(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
{
struct slider *s = (struct slider *) c;
(*(s->onChanged))(uiSlider(s), s->onChangedData);
*lResult = 0;
return TRUE;
}
static void sliderCommitDestroy(uiControl *c)
{
struct slider *s = (struct slider *) c;
uiWindowsUnregisterWM_HSCROLLHandler(s->hwnd);
(*(s->baseCommitDestroy))(uiControl(s));
}
static uintptr_t sliderHandle(uiControl *c)
{
struct slider *s = (struct slider *) c;
return (uintptr_t) (s->hwnd);
}
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
#define sliderWidth 107 /* this is actually the shorter progress bar width, but Microsoft doesn't indicate a width */
#define sliderHeight 15
static void sliderPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
{
*width = uiWindowsDlgUnitsToX(sliderWidth, d->Sys->BaseX);
*height = uiWindowsDlgUnitsToY(sliderHeight, d->Sys->BaseY);
}
static void defaultOnChanged(uiSlider *s, void *data)
{
// do nothing
}
static intmax_t sliderValue(uiSlider *ss)
{
struct slider *s = (struct slider *) ss;
return (intmax_t) SendMessageW(s->hwnd, TBM_GETPOS, 0, 0);
}
static void sliderSetValue(uiSlider *ss, intmax_t value)
{
struct slider *s = (struct slider *) ss;
// don't use TBM_SETPOSNOTIFY; that triggers an event
SendMessageW(s->hwnd, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) value);
}
static void sliderOnChanged(uiSlider *ss, void (*f)(uiSlider *, void *), void *data)
{
struct slider *s = (struct slider *) ss;
s->onChanged = f;
s->onChangedData = data;
}
uiSlider *uiNewSlider(intmax_t min, intmax_t max)
{
struct slider *s;
s = (struct slider *) uiWindowsNewSingleHWNDControl(uiTypeSlider());
s->hwnd = uiWindowsUtilCreateControlHWND(0,
TRACKBAR_CLASSW, L"",
TBS_HORZ | TBS_TOOLTIPS | TBS_TRANSPARENTBKGND | WS_TABSTOP,
hInstance, NULL,
TRUE);
uiWindowsRegisterWM_HSCROLLHandler(s->hwnd, onWM_HSCROLL, uiControl(s));
SendMessageW(s->hwnd, TBM_SETRANGEMIN, (WPARAM) TRUE, (LPARAM) min);
SendMessageW(s->hwnd, TBM_SETRANGEMAX, (WPARAM) TRUE, (LPARAM) max);
SendMessageW(s->hwnd, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) min);
s->onChanged = defaultOnChanged;
uiControl(s)->Handle = sliderHandle;
uiControl(s)->PreferredSize = sliderPreferredSize;
s->baseCommitDestroy = uiControl(s)->CommitDestroy;
uiControl(s)->CommitDestroy = sliderCommitDestroy;
uiSlider(s)->Value = sliderValue;
uiSlider(s)->SetValue = sliderSetValue;
uiSlider(s)->OnChanged = sliderOnChanged;
return uiSlider(s);
}