0

I'm trying to call the GetCaretPos function in User32.dll from an NSIS installer, and the only thing I can seem to get is an invalid access to memory location error.

Here is my code:

Function fixUpRegKeyText
     Exch $0 ; HWND to text box
     Push $1 ; text of edit box
     Push $2 ; pointer to point structure
     Push $3 ; getlasterror result


     System::Alloc 16 ;struct long, long
     pop $2
     ;messageBox MB_OK $2
     ;get the caret position
     System::Call "User32::GetCaretPos(p .r2) i.. ? e"
     pop $3

     messageBox MB_OK $3 ; 998!

     ${NSD_GetText} $0 $1

     Push $1
     call StrUpper
     Pop $1

     ${NSD_SetText} $0 $1

     ; now set the caret position
     ;System::call "user32::SetCaretPos(p s.) i .."

     Pop $3
     Pop $2
     Pop $1
     Pop $0
FunctionEnd

Edit In case anyone is interested in using Windows API to move the text caret, I blogged about it. Using anders' answer, it's straightforward to do this in NSIS script.

davidtbernal
  • 13,434
  • 9
  • 44
  • 60
  • 1
    Ugh, the php guy got mad at the C++ guy and the VB guy tried to salvage it while learning assembly. – Hans Passant Jun 17 '11 at 01:28
  • You're telling me! I was shocked when I first started learning this language (yesterday!) Seeing this, I can't believe how popular this installer framework is! – davidtbernal Jun 17 '11 at 16:24

1 Answers1

1

The p pointer type does not work in 2.46, use i. (Use your offline helpfile, the online helpfile has features only available in SVN)

Also, when a function needs a pointer to a struct that you have allocated, use "i register", not "i .register" (The function needs to know the memory address so it can fill it with data)

System::Call '*(i,i)i.r0'
System::Call "USER32::GetCaretPos(i r0)i.r3"
System::Call '*$0(i.r1,i.r2)'
DetailPrint "$1x$2 return=$3"
System::Free $0
Anders
  • 97,548
  • 12
  • 110
  • 164
  • Awesome, thanks so much. I thought I had already tried using `i`, but I guess I hadn't gotten the right combination of options. The docs are kind of vague. I ended up figuring that that I really needed to use `EM_GETSEL` and `EM_SETSEL` to do what I was trying to do, but your answer helped me get the `SendMessage` calls right. – davidtbernal Jun 17 '11 at 18:42