"I want to call RegisterClassW which takes a pointer to WNDCLASSW as its 
parameter. One of the members of WNDCLASSW is lpszClassName of LPCWSTR type 
(UTF-16 string). This puzzled me as to how I should approach allocating 
storage for that string?"


Win32 API:

RegisterClassW function: 
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassw

Registers a window class for subsequent use in calls to the CreateWindow or 
CreateWindowEx function.

Note:  The RegisterClass function has been superseded by the 
RegisterClassEx function. 

RegisterClassExW function: 
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw

Registers a window class for subsequent use in calls to the CreateWindow or 
CreateWindowEx function.


For RegisterClassExW you can take a look at the Go source code: 
https://go.googlesource.com/go

In src/runtime/syscall_windows_test.go:

    func TestRegisterClass(t *testing.T) {
        kernel32 := GetDLL(t, "kernel32.dll")
        user32 := GetDLL(t, "user32.dll")
        mh, _, _ := kernel32.Proc("GetModuleHandleW").Call(0)
        cb := syscall.NewCallback(func(hwnd syscall.Handle, msg uint32, 
wparam, lparam uintptr) (rc uintptr) {
            t.Fatal("callback should never get called")
            return 0
        })
        type Wndclassex struct {
            Size       uint32
            Style      uint32
            WndProc    uintptr
            ClsExtra   int32
            WndExtra   int32
            Instance   syscall.Handle
            Icon       syscall.Handle
            Cursor     syscall.Handle
            Background syscall.Handle
            MenuName   *uint16
            ClassName  *uint16
            IconSm     syscall.Handle
        }
        name := syscall.StringToUTF16Ptr("test_window")
        wc := Wndclassex{
            WndProc:   cb,
            Instance:  syscall.Handle(mh),
            ClassName: name,
        }
        wc.Size = uint32(unsafe.Sizeof(wc))
        a, _, err := 
user32.Proc("RegisterClassExW").Call(uintptr(unsafe.Pointer(&wc)))
        if a == 0 {
            t.Fatalf("RegisterClassEx failed: %v", err)
        }
        r, _, err := 
user32.Proc("UnregisterClassW").Call(uintptr(unsafe.Pointer(name)), 0)
        if r == 0 {
            t.Fatalf("UnregisterClass failed: %v", err)
        }
    }

For lpszClassName:
 
    name := syscall.StringToUTF16Ptr("test_window")

Peter


On Sunday, October 25, 2020 at 10:23:13 PM UTC-4 Constantine Shablya wrote:

> Hello,
>
> I wish to call some Windows functions, some of which take pointers to types
> which themselves contain pointers. For this purpose I intended to use
> golang.org/x/sys/windows/mkwinsyscall.go and not cgo; in past I have 
> implemented
> a package that uses WASAPI by generating "syscall" bodies with 
> mkwinsyscall.go
> and doing syscall.SyscallN to call virtual functions in COM objects and so 
> have
> some prior experience.
>
> Now I want to call RegisterClassW which takes a pointer to WNDCLASSW as its
> parameter. One of the members of WNDCLASSW is lpszClassName of LPCWSTR type
> (UTF-16 string). This puzzled me as to how I should approach allocating 
> storage
> for that string? Taking into account Go specification making special
> reservations for pointers passed to cgo calls
> (https://golang.org/cmd/cgo/#hdr-Passing_pointers; my guess is that it is
> intended to facilitate possible implementations of moving garbage 
> collectors in
> future) I thought I would have to allocate storage with, say, C.malloc, 
> but that
> would require using cgo which so far I have not had to use. I looked into 
> how Go
> standard library handles this, and I found crypto/x509/root_windows.go
> checkChainSSLServerPolicy
> (
> https://github.com/golang/go/blob/fa98f46741f818913a8c11b877520a548715131f/src/crypto/x509/root_windows.go#L103
> )
> build a chain of pointers and then pass it to
> syscall.CertVerifyCertificateChainPolicy, which is in violation of the cgo
> passing pointers requirement. Although this particular case does not use 
> cgo, I
> believe pointer passing restriction would still apply to it.
>
> All of this made me puzzled, should I store a pointer returned by
> syscall.UTF16PtrFromString (golang.org/x/sys/windows.UTF16PtrFromString) 
> or use
> C.malloc+copy? Or, if the answer isn't straightforward, is it fair to 
> think that
> use of pointer returned by UTF16PtrFromString is more likely to break with 
> newer
> versions of go than C.malloc+copy or is it expected that there will be some
> amendments made to that function when a hypothetical moving GC 
> implementation
> lands?
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/384f662f-5de1-4359-a058-bf63c8b909f8n%40googlegroups.com.

Reply via email to