win32: file dialog
original commit: 7ffff49507231bad77715aecdfec51eb4b9ed2e4
This commit is contained in:
parent
e29c9457e4
commit
d36e3da8be
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
(provide dialog%)
|
(provide dialog%)
|
||||||
|
|
||||||
(define _WORD _short)
|
|
||||||
|
|
||||||
(define-cstruct _DLGTEMPLATE
|
(define-cstruct _DLGTEMPLATE
|
||||||
([style _DWORD]
|
([style _DWORD]
|
||||||
[dwExtendedStyle _DWORD]
|
[dwExtendedStyle _DWORD]
|
||||||
|
|
225
collects/mred/private/wx/win32/filedialog.rkt
Normal file
225
collects/mred/private/wx/win32/filedialog.rkt
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
#lang racket/base
|
||||||
|
(require ffi/unsafe
|
||||||
|
racket/class
|
||||||
|
racket/string
|
||||||
|
"utils.rkt"
|
||||||
|
"types.rkt"
|
||||||
|
"const.rkt"
|
||||||
|
"wndclass.rkt"
|
||||||
|
"../../lock.rkt")
|
||||||
|
|
||||||
|
(provide file-selector)
|
||||||
|
|
||||||
|
(define-cstruct _OPENFILENAME
|
||||||
|
([lStructSize _DWORD]
|
||||||
|
[hwndOwner _HWND]
|
||||||
|
[hInstance _HINSTANCE]
|
||||||
|
[lpstrFilter _permanent-string/utf-16]
|
||||||
|
[lpstrCustomFilter _permanent-string/utf-16]
|
||||||
|
[nMaxCustFilter _DWORD]
|
||||||
|
[nFilterIndex _DWORD]
|
||||||
|
[lpstrFile _pointer]
|
||||||
|
[nMaxFile _DWORD]
|
||||||
|
[lpstrFileTitle _pointer]
|
||||||
|
[nMaxFileTitle _DWORD]
|
||||||
|
[lpstrInitialDir _permanent-string/utf-16]
|
||||||
|
[lpstrTitle _permanent-string/utf-16]
|
||||||
|
[Flags _DWORD]
|
||||||
|
[nFileOffset _WORD]
|
||||||
|
[nFileExtension _WORD]
|
||||||
|
[lpstrDefExt _permanent-string/utf-16]
|
||||||
|
[lCustData _LPARAM]
|
||||||
|
[lpfnHook _fpointer]
|
||||||
|
[lpTemplateName _permanent-string/utf-16]
|
||||||
|
[pvReserved _pointer]
|
||||||
|
[dwReserved _DWORD]
|
||||||
|
[FlagsEx _DWORD]))
|
||||||
|
|
||||||
|
(define-comdlg32 GetSaveFileNameW (_wfun _OPENFILENAME-pointer -> _BOOL))
|
||||||
|
(define-comdlg32 GetOpenFileNameW (_wfun _OPENFILENAME-pointer -> _BOOL))
|
||||||
|
|
||||||
|
(define OFN_READONLY #x00000001)
|
||||||
|
(define OFN_OVERWRITEPROMPT #x00000002)
|
||||||
|
(define OFN_HIDEREADONLY #x00000004)
|
||||||
|
(define OFN_NOCHANGEDIR #x00000008)
|
||||||
|
(define OFN_SHOWHELP #x00000010)
|
||||||
|
(define OFN_ENABLEHOOK #x00000020)
|
||||||
|
(define OFN_ENABLETEMPLATE #x00000040)
|
||||||
|
(define OFN_ENABLETEMPLATEHANDLE #x00000080)
|
||||||
|
(define OFN_ALLOWMULTISELECT #x00000200)
|
||||||
|
(define OFN_EXTENSIONDIFFERENT #x00000400)
|
||||||
|
(define OFN_PATHMUSTEXIST #x00000800)
|
||||||
|
(define OFN_FILEMUSTEXIST #x00001000)
|
||||||
|
(define OFN_NOREADONLYRETURN #x00008000)
|
||||||
|
(define OFN_EXPLORER #x00080000)
|
||||||
|
|
||||||
|
(define BUFFER-LEN 4096)
|
||||||
|
|
||||||
|
(define-cstruct _BROWSEINFO
|
||||||
|
([hwndOwner _HWND]
|
||||||
|
[pidlRoot _pointer]
|
||||||
|
[pszDisplayName _pointer]
|
||||||
|
[lpszTitle _permanent-string/utf-16]
|
||||||
|
[ulFlags _UINT]
|
||||||
|
[lpfn _pointer]
|
||||||
|
[lParam _LPARAM]
|
||||||
|
[iImage _int]))
|
||||||
|
|
||||||
|
(define BIF_RETURNONLYFSDIRS #x00000001)
|
||||||
|
(define BIF_NEWDIALOGSTYLE #x00000040)
|
||||||
|
|
||||||
|
(define-cstruct _IUnknownVtbl
|
||||||
|
([QueryInterface _fpointer]
|
||||||
|
[AddRef _fpointer]
|
||||||
|
[Release (_wfun _pointer -> _ULONG)]))
|
||||||
|
|
||||||
|
(define-cstruct (_IMallocVtbl _IUnknownVtbl)
|
||||||
|
([Alloc _fpointer]
|
||||||
|
[Realloc _fpointer]
|
||||||
|
[Free (_wfun _pointer _pointer -> _void)]
|
||||||
|
[GetSize _fpointer]
|
||||||
|
[DidAlloc _fpointer]
|
||||||
|
[HeapMinimize _fpointer]))
|
||||||
|
|
||||||
|
(define-cstruct _IMalloc
|
||||||
|
([vtbl _IMallocVtbl-pointer]))
|
||||||
|
|
||||||
|
(define (IMalloc-Free im p)
|
||||||
|
((IMallocVtbl-Free (IMalloc-vtbl im)) im p))
|
||||||
|
(define (IMalloc-Release im)
|
||||||
|
((IUnknownVtbl-Release (IMalloc-vtbl im)) im))
|
||||||
|
|
||||||
|
(define-shell32 SHBrowseForFolderW (_wfun _BROWSEINFO-pointer -> _pointer))
|
||||||
|
(define-shell32 SHGetPathFromIDListW (_wfun _pointer _pointer -> _BOOL))
|
||||||
|
(define-shell32 SHGetMalloc (_wfun (p : (_ptr o _IMalloc-pointer)) -> (r : _HRESULT)
|
||||||
|
-> (if (negative? r)
|
||||||
|
(error 'SHGetMalloc "failed: ~s" (bitwise-and #xFFFF r))
|
||||||
|
p)))
|
||||||
|
|
||||||
|
(define (file-selector message directory filename
|
||||||
|
extension
|
||||||
|
filters style parent)
|
||||||
|
(if (memq 'dir style)
|
||||||
|
(dialog-selector message directory
|
||||||
|
style parent)
|
||||||
|
(do-file-selector message directory filename
|
||||||
|
extension
|
||||||
|
filters style parent)))
|
||||||
|
|
||||||
|
(define (do-file-selector message directory filename
|
||||||
|
extension
|
||||||
|
filters style parent)
|
||||||
|
(atomically
|
||||||
|
(let* ([pre-ofn
|
||||||
|
(make-OPENFILENAME
|
||||||
|
(ctype-sizeof _OPENFILENAME)
|
||||||
|
(and parent
|
||||||
|
(send parent get-hwnd))
|
||||||
|
hInstance
|
||||||
|
(string-append
|
||||||
|
(string-join
|
||||||
|
(for/list ([f (in-list filters)])
|
||||||
|
(format "~a\0~a" (car f) (cadr f)))
|
||||||
|
"\0")
|
||||||
|
"\0")
|
||||||
|
#f
|
||||||
|
0
|
||||||
|
0 ; nFilterIndex
|
||||||
|
(malloc 'raw (* BUFFER-LEN (ctype-sizeof _short)))
|
||||||
|
BUFFER-LEN
|
||||||
|
#f
|
||||||
|
0
|
||||||
|
(and directory
|
||||||
|
(path->string (simplify-path directory #f)))
|
||||||
|
message
|
||||||
|
(bitwise-ior
|
||||||
|
OFN_HIDEREADONLY
|
||||||
|
(if (memq 'put style) OFN_OVERWRITEPROMPT 0)
|
||||||
|
(if (memq 'multi style) (bitwise-ior OFN_ALLOWMULTISELECT OFN_EXPLORER) 0)
|
||||||
|
(if directory OFN_NOCHANGEDIR 0))
|
||||||
|
0
|
||||||
|
0
|
||||||
|
extension
|
||||||
|
0
|
||||||
|
#f
|
||||||
|
#f
|
||||||
|
#f
|
||||||
|
0
|
||||||
|
0)]
|
||||||
|
[ofn (malloc 'raw (ctype-sizeof _OPENFILENAME))])
|
||||||
|
(set-cpointer-tag! ofn OPENFILENAME-tag)
|
||||||
|
(memcpy ofn pre-ofn 1 _OPENFILENAME)
|
||||||
|
(if filename
|
||||||
|
(let* ([filename (path->string (simplify-path filename #f))]
|
||||||
|
[len (utf-16-length filename)])
|
||||||
|
(memcpy (OPENFILENAME-lpstrFile ofn)
|
||||||
|
(cast filename _string/utf-16 _gcpointer)
|
||||||
|
(+ len 1)
|
||||||
|
_uint16))
|
||||||
|
(ptr-set! (OPENFILENAME-lpstrFile ofn) _uint16 0))
|
||||||
|
(let ([r (if (memq 'put style)
|
||||||
|
(GetSaveFileNameW ofn)
|
||||||
|
(GetOpenFileNameW ofn))])
|
||||||
|
(begin0
|
||||||
|
(and r
|
||||||
|
(if (memq 'multi style)
|
||||||
|
(let ([strs
|
||||||
|
(let ([p (OPENFILENAME-lpstrFile ofn)])
|
||||||
|
(let loop ([pos 0])
|
||||||
|
(cond
|
||||||
|
[(and (zero? (ptr-ref p _byte pos))
|
||||||
|
(zero? (ptr-ref p _byte (add1 pos))))
|
||||||
|
null]
|
||||||
|
[else (let ([end-pos
|
||||||
|
(let loop ([pos (+ pos 2)])
|
||||||
|
(cond
|
||||||
|
[(and (zero? (ptr-ref p _byte pos))
|
||||||
|
(zero? (ptr-ref p _byte (add1 pos))))
|
||||||
|
pos]
|
||||||
|
[else (loop (+ pos 2))]))])
|
||||||
|
(cons
|
||||||
|
(cast (ptr-add p pos) _pointer _string/utf-16)
|
||||||
|
(loop (+ end-pos 2))))])))])
|
||||||
|
(if ((length strs) . < . 2)
|
||||||
|
#f
|
||||||
|
(map (lambda (p) (build-path (car strs) p))
|
||||||
|
(cdr strs))))
|
||||||
|
(cast (OPENFILENAME-lpstrFile ofn) _pointer _string/utf-16)))
|
||||||
|
(when directory
|
||||||
|
(free (OPENFILENAME-lpstrInitialDir ofn)))
|
||||||
|
(when message
|
||||||
|
(free (OPENFILENAME-lpstrTitle ofn)))
|
||||||
|
(free (OPENFILENAME-lpstrFilter ofn))
|
||||||
|
(free (OPENFILENAME-lpstrFile ofn)))))))
|
||||||
|
|
||||||
|
(define MAX_PATH 4096)
|
||||||
|
|
||||||
|
(define (dialog-selector message directory
|
||||||
|
style parent)
|
||||||
|
(atomically
|
||||||
|
(let ([pre-bi (make-BROWSEINFO
|
||||||
|
(and parent
|
||||||
|
(send parent get-hwnd))
|
||||||
|
#f
|
||||||
|
(malloc 'raw MAX_PATH _uint16)
|
||||||
|
message
|
||||||
|
(bitwise-ior BIF_NEWDIALOGSTYLE BIF_RETURNONLYFSDIRS)
|
||||||
|
#f
|
||||||
|
0
|
||||||
|
0)]
|
||||||
|
[bi (malloc 'raw (ctype-sizeof _BROWSEINFO))])
|
||||||
|
(set-cpointer-tag! bi BROWSEINFO-tag)
|
||||||
|
(memcpy bi pre-bi 1 _BROWSEINFO)
|
||||||
|
(let ([r (SHBrowseForFolderW bi)])
|
||||||
|
(begin0
|
||||||
|
(and r
|
||||||
|
(let ([ok (SHGetPathFromIDListW r (BROWSEINFO-pszDisplayName bi))])
|
||||||
|
(and ok
|
||||||
|
(let ([mi (SHGetMalloc)])
|
||||||
|
(IMalloc-Free mi r)
|
||||||
|
(IMalloc-Release mi))
|
||||||
|
(string->path
|
||||||
|
(cast (BROWSEINFO-pszDisplayName bi) _pointer _string/utf-16)))))
|
||||||
|
(free (BROWSEINFO-pszDisplayName bi))
|
||||||
|
(when message
|
||||||
|
(free (BROWSEINFO-lpszTitle bi))))))))
|
|
@ -9,6 +9,7 @@
|
||||||
"menu-item.rkt"
|
"menu-item.rkt"
|
||||||
"frame.rkt"
|
"frame.rkt"
|
||||||
"dc.rkt"
|
"dc.rkt"
|
||||||
|
"filedialog.rkt"
|
||||||
racket/draw)
|
racket/draw)
|
||||||
|
|
||||||
(provide
|
(provide
|
||||||
|
@ -87,7 +88,6 @@
|
||||||
(define (get-display-depth) 32)
|
(define (get-display-depth) 32)
|
||||||
|
|
||||||
(define-unimplemented is-color-display?)
|
(define-unimplemented is-color-display?)
|
||||||
(define-unimplemented file-selector)
|
|
||||||
(define-unimplemented show-print-setup)
|
(define-unimplemented show-print-setup)
|
||||||
(define (can-show-print-setup?) #f)
|
(define (can-show-print-setup?) #f)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
(provide _wfun
|
(provide _wfun
|
||||||
|
|
||||||
|
_WORD
|
||||||
_DWORD
|
_DWORD
|
||||||
_UDWORD
|
_UDWORD
|
||||||
_ATOM
|
_ATOM
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
_UINT_PTR
|
_UINT_PTR
|
||||||
_BYTE
|
_BYTE
|
||||||
_LONG
|
_LONG
|
||||||
|
_ULONG
|
||||||
_SHORT
|
_SHORT
|
||||||
_HRESULT
|
_HRESULT
|
||||||
_WCHAR
|
_WCHAR
|
||||||
|
@ -35,6 +37,7 @@
|
||||||
_fnpointer
|
_fnpointer
|
||||||
|
|
||||||
_permanent-string/utf-16
|
_permanent-string/utf-16
|
||||||
|
utf-16-length
|
||||||
|
|
||||||
(struct-out POINT) _POINT _POINT-pointer
|
(struct-out POINT) _POINT _POINT-pointer
|
||||||
(struct-out RECT) _RECT _RECT-pointer
|
(struct-out RECT) _RECT _RECT-pointer
|
||||||
|
@ -48,6 +51,7 @@
|
||||||
(define-syntax-rule (_wfun . a)
|
(define-syntax-rule (_wfun . a)
|
||||||
(_fun #:abi 'stdcall . a))
|
(_fun #:abi 'stdcall . a))
|
||||||
|
|
||||||
|
(define _WORD _int16)
|
||||||
(define _DWORD _int32)
|
(define _DWORD _int32)
|
||||||
(define _UDWORD _uint32)
|
(define _UDWORD _uint32)
|
||||||
(define _ATOM _int)
|
(define _ATOM _int)
|
||||||
|
@ -77,6 +81,13 @@
|
||||||
|
|
||||||
(define _fnpointer (_or-null _fpointer))
|
(define _fnpointer (_or-null _fpointer))
|
||||||
|
|
||||||
|
(define (utf-16-length s)
|
||||||
|
(for/fold ([len 0]) ([c (in-string s)])
|
||||||
|
(+ len
|
||||||
|
(if ((char->integer c) . > . #xFFFF)
|
||||||
|
2
|
||||||
|
1))))
|
||||||
|
|
||||||
(define _permanent-string/utf-16
|
(define _permanent-string/utf-16
|
||||||
(make-ctype _pointer
|
(make-ctype _pointer
|
||||||
(lambda (s)
|
(lambda (s)
|
||||||
|
@ -84,16 +95,14 @@
|
||||||
(let ([v (malloc _gcpointer)])
|
(let ([v (malloc _gcpointer)])
|
||||||
(ptr-set! v _string/utf-16 s)
|
(ptr-set! v _string/utf-16 s)
|
||||||
(let ([p (ptr-ref v _gcpointer)])
|
(let ([p (ptr-ref v _gcpointer)])
|
||||||
(let ([len (let loop ([i 0])
|
(let ([len (+ 1 (utf-16-length s))])
|
||||||
(if (zero? (ptr-ref p _uint16 i))
|
|
||||||
(add1 i)
|
|
||||||
(loop (add1 i))))])
|
|
||||||
(let ([c (malloc len _uint16 'raw)])
|
(let ([c (malloc len _uint16 'raw)])
|
||||||
(memcpy c p len _uint16)
|
(memcpy c p len _uint16)
|
||||||
c))))))
|
c))))))
|
||||||
(lambda (p) p)))
|
(lambda (p) p)))
|
||||||
|
|
||||||
(define _LONG _long)
|
(define _LONG _long)
|
||||||
|
(define _ULONG _ulong)
|
||||||
(define _SHORT _short)
|
(define _SHORT _short)
|
||||||
|
|
||||||
(define-cstruct _POINT ([x _LONG]
|
(define-cstruct _POINT ([x _LONG]
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
define-user32
|
define-user32
|
||||||
define-kernel32
|
define-kernel32
|
||||||
define-comctl32
|
define-comctl32
|
||||||
|
define-comdlg32
|
||||||
define-shell32
|
define-shell32
|
||||||
define-uxtheme
|
define-uxtheme
|
||||||
define-mz
|
define-mz
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
(define user32-lib (ffi-lib "user32.dll"))
|
(define user32-lib (ffi-lib "user32.dll"))
|
||||||
(define kernel32-lib (ffi-lib "kernel32.dll"))
|
(define kernel32-lib (ffi-lib "kernel32.dll"))
|
||||||
(define comctl32-lib (ffi-lib "comctl32.dll"))
|
(define comctl32-lib (ffi-lib "comctl32.dll"))
|
||||||
|
(define comdlg32-lib (ffi-lib "comdlg32.dll"))
|
||||||
(define shell32-lib (ffi-lib "shell32.dll"))
|
(define shell32-lib (ffi-lib "shell32.dll"))
|
||||||
(define uxtheme-lib (ffi-lib "uxtheme.dll"))
|
(define uxtheme-lib (ffi-lib "uxtheme.dll"))
|
||||||
|
|
||||||
|
@ -52,6 +54,7 @@
|
||||||
(define-ffi-definer define-user32 user32-lib)
|
(define-ffi-definer define-user32 user32-lib)
|
||||||
(define-ffi-definer define-kernel32 kernel32-lib)
|
(define-ffi-definer define-kernel32 kernel32-lib)
|
||||||
(define-ffi-definer define-comctl32 comctl32-lib)
|
(define-ffi-definer define-comctl32 comctl32-lib)
|
||||||
|
(define-ffi-definer define-comdlg32 comdlg32-lib)
|
||||||
(define-ffi-definer define-shell32 shell32-lib)
|
(define-ffi-definer define-shell32 shell32-lib)
|
||||||
(define-ffi-definer define-uxtheme uxtheme-lib)
|
(define-ffi-definer define-uxtheme uxtheme-lib)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user