156 lines
4.2 KiB
Go
156 lines
4.2 KiB
Go
// Copyright 2010-2012 The W32 Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build windows
|
|
|
|
package w32
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
var (
|
|
modshell32 = syscall.NewLazyDLL("shell32.dll")
|
|
|
|
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolderW")
|
|
procSHGetPathFromIDList = modshell32.NewProc("SHGetPathFromIDListW")
|
|
procDragAcceptFiles = modshell32.NewProc("DragAcceptFiles")
|
|
procDragQueryFile = modshell32.NewProc("DragQueryFileW")
|
|
procDragQueryPoint = modshell32.NewProc("DragQueryPoint")
|
|
procDragFinish = modshell32.NewProc("DragFinish")
|
|
procShellExecute = modshell32.NewProc("ShellExecuteW")
|
|
procExtractIcon = modshell32.NewProc("ExtractIconW")
|
|
)
|
|
|
|
func SHBrowseForFolder(bi *BROWSEINFO) uintptr {
|
|
ret, _, _ := procSHBrowseForFolder.Call(uintptr(unsafe.Pointer(bi)))
|
|
|
|
return ret
|
|
}
|
|
|
|
func SHGetPathFromIDList(idl uintptr) string {
|
|
buf := make([]uint16, 1024)
|
|
procSHGetPathFromIDList.Call(
|
|
idl,
|
|
uintptr(unsafe.Pointer(&buf[0])))
|
|
|
|
return syscall.UTF16ToString(buf)
|
|
}
|
|
|
|
func DragAcceptFiles(hwnd HWND, accept bool) {
|
|
procDragAcceptFiles.Call(
|
|
uintptr(hwnd),
|
|
uintptr(BoolToBOOL(accept)))
|
|
}
|
|
|
|
func DragQueryFile(hDrop HDROP, iFile uint) (fileName string, fileCount uint) {
|
|
ret, _, _ := procDragQueryFile.Call(
|
|
uintptr(hDrop),
|
|
uintptr(iFile),
|
|
0,
|
|
0)
|
|
|
|
fileCount = uint(ret)
|
|
|
|
if iFile != 0xFFFFFFFF {
|
|
buf := make([]uint16, fileCount+1)
|
|
|
|
ret, _, _ := procDragQueryFile.Call(
|
|
uintptr(hDrop),
|
|
uintptr(iFile),
|
|
uintptr(unsafe.Pointer(&buf[0])),
|
|
uintptr(fileCount+1))
|
|
|
|
if ret == 0 {
|
|
panic("Invoke DragQueryFile error.")
|
|
}
|
|
|
|
fileName = syscall.UTF16ToString(buf)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func DragQueryPoint(hDrop HDROP) (x, y int, isClientArea bool) {
|
|
var pt POINT
|
|
ret, _, _ := procDragQueryPoint.Call(
|
|
uintptr(hDrop),
|
|
uintptr(unsafe.Pointer(&pt)))
|
|
|
|
return int(pt.X), int(pt.Y), (ret == 1)
|
|
}
|
|
|
|
func DragFinish(hDrop HDROP) {
|
|
procDragFinish.Call(uintptr(hDrop))
|
|
}
|
|
|
|
func ShellExecute(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
|
|
var op, param, directory uintptr
|
|
if len(lpOperation) != 0 {
|
|
op = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation)))
|
|
}
|
|
if len(lpParameters) != 0 {
|
|
param = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters)))
|
|
}
|
|
if len(lpDirectory) != 0 {
|
|
directory = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory)))
|
|
}
|
|
|
|
ret, _, _ := procShellExecute.Call(
|
|
uintptr(hwnd),
|
|
op,
|
|
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))),
|
|
param,
|
|
directory,
|
|
uintptr(nShowCmd))
|
|
|
|
errorMsg := ""
|
|
if ret != 0 && ret <= 32 {
|
|
switch int(ret) {
|
|
case ERROR_FILE_NOT_FOUND:
|
|
errorMsg = "The specified file was not found."
|
|
case ERROR_PATH_NOT_FOUND:
|
|
errorMsg = "The specified path was not found."
|
|
case ERROR_BAD_FORMAT:
|
|
errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)."
|
|
case SE_ERR_ACCESSDENIED:
|
|
errorMsg = "The operating system denied access to the specified file."
|
|
case SE_ERR_ASSOCINCOMPLETE:
|
|
errorMsg = "The file name association is incomplete or invalid."
|
|
case SE_ERR_DDEBUSY:
|
|
errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed."
|
|
case SE_ERR_DDEFAIL:
|
|
errorMsg = "The DDE transaction failed."
|
|
case SE_ERR_DDETIMEOUT:
|
|
errorMsg = "The DDE transaction could not be completed because the request timed out."
|
|
case SE_ERR_DLLNOTFOUND:
|
|
errorMsg = "The specified DLL was not found."
|
|
case SE_ERR_NOASSOC:
|
|
errorMsg = "There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable."
|
|
case SE_ERR_OOM:
|
|
errorMsg = "There was not enough memory to complete the operation."
|
|
case SE_ERR_SHARE:
|
|
errorMsg = "A sharing violation occurred."
|
|
default:
|
|
errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", ret)
|
|
}
|
|
} else {
|
|
return nil
|
|
}
|
|
|
|
return errors.New(errorMsg)
|
|
}
|
|
|
|
func ExtractIcon(lpszExeFileName string, nIconIndex int) HICON {
|
|
ret, _, _ := procExtractIcon.Call(
|
|
0,
|
|
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpszExeFileName))),
|
|
uintptr(nIconIndex))
|
|
|
|
return HICON(ret)
|
|
}
|