From 418cd141e01ef4720226d6e0cd284dff988203d6 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Thu, 24 Mar 2022 12:51:28 +0000 Subject: [PATCH] Refactor. --- entry_windows.go | 65 +++++++++--------- list_windows.go | 74 +++++++++++---------- progress_windows.go | 156 ++++++++++++++++++++++---------------------- 3 files changed, 153 insertions(+), 142 deletions(-) diff --git a/entry_windows.go b/entry_windows.go index 629da75..32b0838 100644 --- a/entry_windows.go +++ b/entry_windows.go @@ -16,8 +16,26 @@ func entry(text string, opts options) (string, error) { opts.cancelLabel = stringPtr("Cancel") } + dlg := &entryDialog{} + return dlg.setup(text, opts) +} + +type entryDialog struct { + out string + err error + + wnd uintptr + textCtl uintptr + editCtl uintptr + okBtn uintptr + cancelBtn uintptr + extraBtn uintptr + font font +} + +func (dlg *entryDialog) setup(text string, opts options) (string, error) { defer setup()() - dlg := &entryDialog{font: getFont()} + dlg.font = getFont() defer dlg.font.delete() if opts.ctx != nil && opts.ctx.Err() != nil { @@ -98,36 +116,23 @@ func entry(text string, opts options) (string, error) { return dlg.out, dlg.err } -type entryDialog struct { - out string - err error - - wnd uintptr - textCtl uintptr - editCtl uintptr - okBtn uintptr - cancelBtn uintptr - extraBtn uintptr - font font -} - -func (d *entryDialog) layout(dpi dpi) { - font := d.font.forDPI(dpi) - sendMessage.Call(d.textCtl, 0x0030 /* WM_SETFONT */, font, 1) - sendMessage.Call(d.editCtl, 0x0030 /* WM_SETFONT */, font, 1) - sendMessage.Call(d.okBtn, 0x0030 /* WM_SETFONT */, font, 1) - sendMessage.Call(d.cancelBtn, 0x0030 /* WM_SETFONT */, font, 1) - sendMessage.Call(d.extraBtn, 0x0030 /* WM_SETFONT */, font, 1) - setWindowPos.Call(d.wnd, 0, 0, 0, dpi.scale(281), dpi.scale(141), 0x6) // SWP_NOZORDER|SWP_NOMOVE - setWindowPos.Call(d.textCtl, 0, dpi.scale(12), dpi.scale(10), dpi.scale(241), dpi.scale(16), 0x4) // SWP_NOZORDER - setWindowPos.Call(d.editCtl, 0, dpi.scale(12), dpi.scale(30), dpi.scale(241), dpi.scale(24), 0x4) // SWP_NOZORDER - if d.extraBtn == 0 { - setWindowPos.Call(d.okBtn, 0, dpi.scale(95), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER - setWindowPos.Call(d.cancelBtn, 0, dpi.scale(178), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER +func (dlg *entryDialog) layout(dpi dpi) { + font := dlg.font.forDPI(dpi) + sendMessage.Call(dlg.textCtl, 0x0030 /* WM_SETFONT */, font, 1) + sendMessage.Call(dlg.editCtl, 0x0030 /* WM_SETFONT */, font, 1) + sendMessage.Call(dlg.okBtn, 0x0030 /* WM_SETFONT */, font, 1) + sendMessage.Call(dlg.cancelBtn, 0x0030 /* WM_SETFONT */, font, 1) + sendMessage.Call(dlg.extraBtn, 0x0030 /* WM_SETFONT */, font, 1) + setWindowPos.Call(dlg.wnd, 0, 0, 0, dpi.scale(281), dpi.scale(141), 0x6) // SWP_NOZORDER|SWP_NOMOVE + setWindowPos.Call(dlg.textCtl, 0, dpi.scale(12), dpi.scale(10), dpi.scale(241), dpi.scale(16), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.editCtl, 0, dpi.scale(12), dpi.scale(30), dpi.scale(241), dpi.scale(24), 0x4) // SWP_NOZORDER + if dlg.extraBtn == 0 { + setWindowPos.Call(dlg.okBtn, 0, dpi.scale(95), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.cancelBtn, 0, dpi.scale(178), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER } else { - setWindowPos.Call(d.okBtn, 0, dpi.scale(12), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER - setWindowPos.Call(d.extraBtn, 0, dpi.scale(95), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER - setWindowPos.Call(d.cancelBtn, 0, dpi.scale(178), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.okBtn, 0, dpi.scale(12), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.extraBtn, 0, dpi.scale(95), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.cancelBtn, 0, dpi.scale(178), dpi.scale(66), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER } } diff --git a/list_windows.go b/list_windows.go index 04fc188..313bb84 100644 --- a/list_windows.go +++ b/list_windows.go @@ -28,12 +28,31 @@ func listDlg(text string, items []string, multiple bool, opts options) ([]string opts.cancelLabel = stringPtr("Cancel") } - defer setup()() dlg := &listDialog{ items: items, multiple: multiple, - font: getFont(), } + return dlg.setup(text, opts) +} + +type listDialog struct { + items []string + multiple bool + out []string + err error + + wnd uintptr + textCtl uintptr + listCtl uintptr + okBtn uintptr + cancelBtn uintptr + extraBtn uintptr + font font +} + +func (dlg *listDialog) setup(text string, opts options) ([]string, error) { + defer setup()() + dlg.font = getFont() defer dlg.font.delete() if opts.ctx != nil && opts.ctx.Err() != nil { @@ -64,7 +83,7 @@ func listDlg(text string, items []string, multiple bool, opts options) ([]string 12, 10, 241, 16, dlg.wnd, 0, instance, 0) var flags uintptr = 0x50320000 // WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_GROUP|WS_TABSTOP - if multiple { + if dlg.multiple { flags |= 0x0800 // LBS_EXTENDEDSEL } dlg.listCtl, _, _ = createWindowEx.Call(0x200, // WS_EX_CLIENTEDGE @@ -87,7 +106,7 @@ func listDlg(text string, items []string, multiple bool, opts options) ([]string 12, 206, 75, 24, dlg.wnd, 7 /* IDNO */, instance, 0) } - for _, item := range items { + for _, item := range dlg.items { sendMessage.Call(dlg.listCtl, 0x180 /* LB_ADDSTRING */, 0, strptr(item)) } @@ -117,38 +136,23 @@ func listDlg(text string, items []string, multiple bool, opts options) ([]string return dlg.out, dlg.err } -type listDialog struct { - items []string - multiple bool - out []string - err error - - wnd uintptr - textCtl uintptr - listCtl uintptr - okBtn uintptr - cancelBtn uintptr - extraBtn uintptr - font font -} - -func (d *listDialog) layout(dpi dpi) { - font := d.font.forDPI(dpi) - sendMessage.Call(d.textCtl, 0x0030 /* WM_SETFONT */, font, 1) - sendMessage.Call(d.listCtl, 0x0030 /* WM_SETFONT */, font, 1) - sendMessage.Call(d.okBtn, 0x0030 /* WM_SETFONT */, font, 1) - sendMessage.Call(d.cancelBtn, 0x0030 /* WM_SETFONT */, font, 1) - sendMessage.Call(d.extraBtn, 0x0030 /* WM_SETFONT */, font, 1) - setWindowPos.Call(d.wnd, 0, 0, 0, dpi.scale(281), dpi.scale(281), 0x6) // SWP_NOZORDER|SWP_NOMOVE - setWindowPos.Call(d.textCtl, 0, dpi.scale(12), dpi.scale(10), dpi.scale(241), dpi.scale(16), 0x4) // SWP_NOZORDER - setWindowPos.Call(d.listCtl, 0, dpi.scale(12), dpi.scale(30), dpi.scale(241), dpi.scale(164), 0x4) // SWP_NOZORDER - if d.extraBtn == 0 { - setWindowPos.Call(d.okBtn, 0, dpi.scale(95), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER - setWindowPos.Call(d.cancelBtn, 0, dpi.scale(178), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER +func (dlg *listDialog) layout(dpi dpi) { + font := dlg.font.forDPI(dpi) + sendMessage.Call(dlg.textCtl, 0x0030 /* WM_SETFONT */, font, 1) + sendMessage.Call(dlg.listCtl, 0x0030 /* WM_SETFONT */, font, 1) + sendMessage.Call(dlg.okBtn, 0x0030 /* WM_SETFONT */, font, 1) + sendMessage.Call(dlg.cancelBtn, 0x0030 /* WM_SETFONT */, font, 1) + sendMessage.Call(dlg.extraBtn, 0x0030 /* WM_SETFONT */, font, 1) + setWindowPos.Call(dlg.wnd, 0, 0, 0, dpi.scale(281), dpi.scale(281), 0x6) // SWP_NOZORDER|SWP_NOMOVE + setWindowPos.Call(dlg.textCtl, 0, dpi.scale(12), dpi.scale(10), dpi.scale(241), dpi.scale(16), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.listCtl, 0, dpi.scale(12), dpi.scale(30), dpi.scale(241), dpi.scale(164), 0x4) // SWP_NOZORDER + if dlg.extraBtn == 0 { + setWindowPos.Call(dlg.okBtn, 0, dpi.scale(95), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.cancelBtn, 0, dpi.scale(178), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER } else { - setWindowPos.Call(d.okBtn, 0, dpi.scale(12), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER - setWindowPos.Call(d.extraBtn, 0, dpi.scale(95), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER - setWindowPos.Call(d.cancelBtn, 0, dpi.scale(178), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.okBtn, 0, dpi.scale(12), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.extraBtn, 0, dpi.scale(95), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER + setWindowPos.Call(dlg.cancelBtn, 0, dpi.scale(178), dpi.scale(206), dpi.scale(75), dpi.scale(24), 0x4) // SWP_NOZORDER } } diff --git a/progress_windows.go b/progress_windows.go index 07a9d7c..470833b 100644 --- a/progress_windows.go +++ b/progress_windows.go @@ -33,11 +33,7 @@ func progress(opts options) (ProgressDialog, error) { dlg.init.Add(1) go func() { - err := progressDlg(opts, dlg) - if cerr := opts.ctx.Err(); cerr != nil { - err = cerr - } - dlg.err = err + dlg.err = dlg.setup(opts) close(dlg.done) }() @@ -45,8 +41,83 @@ func progress(opts options) (ProgressDialog, error) { return dlg, nil } -func progressDlg(opts options, dlg *progressDialog) error { - defer dlg.init.Done() +type progressDialog struct { + init sync.WaitGroup + done chan struct{} + max int + err error + + wnd uintptr + textCtl uintptr + progCtl uintptr + okBtn uintptr + cancelBtn uintptr + extraBtn uintptr + font font +} + +func (d *progressDialog) Text(text string) error { + select { + default: + setWindowText.Call(d.textCtl, strptr(text)) + return nil + case <-d.done: + return d.err + } +} + +func (d *progressDialog) Value(value int) error { + select { + default: + sendMessage.Call(d.progCtl, 0x402 /* PBM_SETPOS */, uintptr(value), 0) + if value >= d.max { + enableWindow.Call(d.okBtn, 1) + } + return nil + case <-d.done: + return d.err + } +} + +func (d *progressDialog) MaxValue() int { + return d.max +} + +func (d *progressDialog) Done() <-chan struct{} { + return d.done +} + +func (d *progressDialog) Complete() error { + select { + default: + setWindowLong.Call(d.progCtl, intptr(-16) /* GWL_STYLE */, 0x50000001 /* WS_CHILD|WS_VISIBLE|PBS_SMOOTH */) + sendMessage.Call(d.progCtl, 0x406 /* PBM_SETRANGE32 */, 0, 1) + sendMessage.Call(d.progCtl, 0x402 /* PBM_SETPOS */, 1, 0) + enableWindow.Call(d.okBtn, 1) + enableWindow.Call(d.cancelBtn, 0) + return nil + case <-d.done: + return d.err + } +} + +func (d *progressDialog) Close() error { + sendMessage.Call(d.wnd, 0x0112 /* WM_SYSCOMMAND */, 0xf060 /* SC_CLOSE */, 0) + <-d.done + if d.err == ErrCanceled { + return nil + } + return d.err +} + +func (dlg *progressDialog) setup(opts options) error { + done := false + defer func() { + if !done { + dlg.init.Done() + } + }() + defer setup()() dlg.font = getFont() defer dlg.font.delete() @@ -112,8 +183,8 @@ func progressDlg(opts options, dlg *progressDialog) error { } else { sendMessage.Call(dlg.progCtl, 0x406 /* PBM_SETRANGE32 */, 0, uintptr(opts.maxValue)) } - defer dlg.init.Add(1) dlg.init.Done() + done = true if opts.ctx != nil { wait := make(chan struct{}) @@ -136,75 +207,6 @@ func progressDlg(opts options, dlg *progressDialog) error { return dlg.err } -type progressDialog struct { - done chan struct{} - init sync.WaitGroup - max int - err error - - wnd uintptr - textCtl uintptr - progCtl uintptr - okBtn uintptr - cancelBtn uintptr - extraBtn uintptr - font font -} - -func (d *progressDialog) Text(text string) error { - select { - default: - setWindowText.Call(d.textCtl, strptr(text)) - return nil - case <-d.done: - return d.err - } -} - -func (d *progressDialog) Value(value int) error { - select { - default: - sendMessage.Call(d.progCtl, 0x402 /* PBM_SETPOS */, uintptr(value), 0) - if value >= d.max { - enableWindow.Call(d.okBtn, 1) - } - return nil - case <-d.done: - return d.err - } -} - -func (d *progressDialog) MaxValue() int { - return d.max -} - -func (d *progressDialog) Done() <-chan struct{} { - return d.done -} - -func (d *progressDialog) Complete() error { - select { - default: - setWindowLong.Call(d.progCtl, intptr(-16) /* GWL_STYLE */, 0x50000001 /* WS_CHILD|WS_VISIBLE|PBS_SMOOTH */) - sendMessage.Call(d.progCtl, 0x406 /* PBM_SETRANGE32 */, 0, 1) - sendMessage.Call(d.progCtl, 0x402 /* PBM_SETPOS */, 1, 0) - enableWindow.Call(d.okBtn, 1) - enableWindow.Call(d.cancelBtn, 0) - return nil - case <-d.done: - return d.err - } -} - -func (d *progressDialog) Close() error { - sendMessage.Call(d.wnd, 0x0112 /* WM_SYSCOMMAND */, 0xf060 /* SC_CLOSE */, 0) - <-d.done - if d.err == ErrCanceled { - return nil - } - return d.err -} - func (d *progressDialog) layout(dpi dpi) { font := d.font.forDPI(dpi) sendMessage.Call(d.textCtl, 0x0030 /* WM_SETFONT */, font, 1)