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)
 | 
						|
}
 |