AutoHotkey Community

It is currently May 27th, 2012, 8:31 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 34 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Simple Change to IniRead
PostPosted: April 4th, 2006, 9:02 pm 
Offline

Joined: September 2nd, 2004, 1:08 am
Posts: 124
Location: Sunnyvale
I think GetPrivateProfileString is used with IniRead and if we can mod the call to allow for a null Section parameter or a null Key parameter, then the call would return all section names or key names, respectively, from an INI file.

Reference:
http://msdn.microsoft.com/library/defau ... string.asp

"lpAppName
[in] The name of the section containing the key name. If this parameter is NULL, the GetPrivateProfileString function copies all section names in the file to the supplied buffer.
lpKeyName
[in] The name of the key whose associated string is to be retrieved. If this parameter is NULL, all key names in the section specified by the lpAppName parameter are copied to the buffer specified by the lpReturnedString parameter.".


Chris, can we get this implemented?

I already know about IniKeyGet, but this could be a better option in some cases...

_________________
I am he of whom he speaks!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 5th, 2006, 8:33 am 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
IniKeyGet? What is it? Even Google returned nothing on this word.

BTW, I spotted a typo in the IniRead page: Key | The key name in the in the .ini file.
(stupid BBCode that doesn't allow nesting of color tags...)

I don't know if INI files are so much used, nowadays, that such functionnality is to be implemented. If so, I suppose it could be made on the model of Loop (registry). Otherwise, perhaps a DllCall solution is to be implemented.

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 5th, 2006, 10:45 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
I'll add this to the to-do list; thanks. If you need it right away, hopefully it can be done with DllCall.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 5th, 2006, 3:58 pm 
Offline

Joined: September 2nd, 2004, 1:08 am
Posts: 124
Location: Sunnyvale
PhiLho wrote:
IniKeyGet? What is it? Even Google returned nothing on this word.


Hehe, did you search the Autohotkey site? :D
Info here:
http://www.autohotkey.com/forum/viewtop ... =inikeyget

_________________
I am he of whom he speaks!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 5th, 2006, 8:30 pm 
Offline

Joined: September 2nd, 2004, 1:08 am
Posts: 124
Location: Sunnyvale
I have the basic DllCall created and it works:
VarSetCapacity( buff, 10000 )
i:=10000
numchar:=DllCall("kernel32.dll\GetPrivateProfileString",Str,"Section",Str,"Key",Str,"Default",Str,buff,Int,i,Str,"C:\autokey\scripts\test.ini",Int)
msgbox, % buff

Now the issue is with my suggestion of retrieving all the section or key names. I can get it to work, and the buffer contains all key names, but they are nul char delimited. Any suggestions how I can split the buffer using a nul character as the delimiter?

Note that if you want to pass a section or key param as NULL with this call, use Int,0.

_________________
I am he of whom he speaks!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 5th, 2006, 10:25 pm 
Offline

Joined: September 2nd, 2004, 1:08 am
Posts: 124
Location: Sunnyvale
Ok, got it working. I had to convert the binary string to hex, change the nuls to newlines and convert the hex string back to binary. I utilized the Bin2Hex and Hex2Bin functions written by Laszlo (thanks!) with a one line modification of Bin2Hex.

Here is my code:

Code:

VarSetCapacity( buff, 10000 )
i:=10000

; Normal - Return Value of Key
numchars:=DllCall("kernel32.dll\GetPrivateProfileString",Str,"Section",Str,"Key",Str,"Default",Str,buff,Int,i,Str,"C:\a.ini",Int) 

msgbox,% "Value: " . buff
 
; Return Key names
numchars:=DllCall("kernel32.dll\GetPrivateProfileString",Str,"Section",Int,0,Str,"Default",Str,buff,Int,i,Str,"C:\a.ini",Int)

Bin2Hex(knb,buff,numchars)
StringReplace, knb, knb,-00,0A, All
StringReplace, knb, knb,-,, All
Hex2Bin(knames,knb,numchars)

msgbox,% "Key Names: " . knames

; Return Section names
numchars:=DllCall("kernel32.dll\GetPrivateProfileString",Int,0,Int,0,Str,"Default",Str,buff,Int,i,Str,"C:\a.ini",Int)

Bin2Hex(snb,buff,numchars)
StringReplace, snb, snb,-00,0A, All
StringReplace, snb, snb,-,, All
Hex2Bin(snames,snb,numchars)

msgbox,% "Section Names: ". snames

Return

Bin2Hex(ByRef h, ByRef b, n=0)      ; n bytes binary data -> stream of 2-digit
;hex
{         
                         ; n = 0: all (SetCapacity can be larger than used!)
   format = %A_FormatInteger%       ; save original integer format
   SetFormat Integer, Hex           ; for converting bytes to hex

   m := VarSetCapacity(b)
   If (n < 1 or n > m)
       n := m
   Address := &b
   h =
   Loop %n%
   {
      x := *Address                 ; get byte in hex
      StringTrimLeft x, x, 2        ; remove 0x
      x = 0%x%                      ; pad left
      StringRight x, x, 2           ; 2 hex digits
      h = %h%-%x%                   ; modded for null character identification
      Address++
   }
   SetFormat Integer, %format%      ; restore original format
}

Hex2Bin(ByRef b, h, n=0)            ; n hex digit-pairs -> binary data
{                                   ; n = 0: all. (Only ByRef can handle binaries)
   m := Ceil(StrLen(h)/2)
   If (n < 1 or n > m)
       n := m
   Granted := VarSetCapacity(b, n, 33)
   IfLess Granted,%n%, {
      ErrorLevel = Mem=%Granted%
      Return
   }
   StringLeft b, b, n
   Address := &b
   Loop %n%
   {
      StringLeft  x, h, 2
      StringTrimLeft h, h, 2
      x = 0x%x%
      DllCall("RtlFillMemory", "UInt", Address, "UInt", 1, "UChar", x)
      Address++
   }
}


I threw this all together rather quickly so it may have an issue or three.

_________________
I am he of whom he speaks!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 5th, 2006, 11:41 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Try CharReplace(buff,0,13,numchars) with this function
Code:
CharReplace(ByRef Buf, Ch1, Ch2, Len=0) {
   m := VarSetCapacity(Buf)
   If (Len < 1 or Len > m)
       Len = %m%
   Loop %Len%
      If (*(&Buf+A_Index-1) = Ch1)
         DllCall("RtlFillMemory", UInt,&Buf+A_Index-1, UInt,1, UInt,Ch2)
}

Edit: fixed typo: 1st param at call must be the buffer name.


Last edited by Laszlo on April 6th, 2006, 3:47 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 6th, 2006, 1:01 am 
Offline

Joined: September 2nd, 2004, 1:08 am
Posts: 124
Location: Sunnyvale
I tried it with CharReplace(buff,0,13,numchars) and it seemed to choke when it got to the first nul character in the string. In other words, it returned the first key name and then a garbage char, then nothing... Does it work for you? If so, please post INI and example code. Thx

_________________
I am he of whom he speaks!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 6th, 2006, 3:42 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Sorry, the 1st parameter has to be "buff", of course, as you noticed. It works for me (Win XP, SP2, AHK 1.0.43.04):
Code:
i = 10000
VarSetCapacity( buff, i )

; Return Key names
numchars:=DllCall("kernel32.dll\GetPrivateProfileString",Str,"HotKeys"
   ,Int,0,Str,"???",Str,buff,Int,i,Str,"c:\t\AutoHotKey\SKey.ini",Int)
CharReplace(buff, 0, 13, numchars)
MsgBox %buff%

CharReplace(ByRef Buf, Ch1, Ch2, Len=0) { ; In Buf all char Ch1 is replaced with Ch2 (NUL:0->`n:13)
   m := VarSetCapacity(Buf)
   If (Len < 1 or Len > m)
       Len = %m%
   Loop %Len%
      If (*(&Buf+A_Index-1) = Ch1)
         DllCall("RtlFillMemory", UInt,&Buf+A_Index-1, UInt,1, UInt,Ch2)
}
My ini file looks like
Code:
[ProcessDefaults]
ANSI =Mew32.exe,sbrowser.exe,pdexplo.exe
Unicode =WinWord.exe,PowerPnt.exe,WordPad.exe,Notepad.exe,IEXPLORE.EXE,nlnotes.exe,WINWORD.EXE
OFF =MathKernel.exe,Matlab.exe,Calc.exe

[HotKeys]
ForwardKey  = CapsLock
BackwardKey = CapsLock & LShift
SymbolUpKey = CapsLock & Tab
SymbolDnKey = CapsLock & q
ReplaceKey  = CapsLock & r
GuiWindKey  = !CapsLock

[ANSIcodeRings]
...and the MsgBox shows
Code:
---------------------------
w.ahk
---------------------------
ForwardKey
BackwardKey
SymbolUpKey
SymbolDnKey
ReplaceKey
GuiWindKey
---------------------------
OK   
---------------------------


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 6th, 2006, 6:36 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2545
Code:
IniReadEx(IFile, ISect="", IKey="", Delim=124, buffsz=10000)
{
  IfNotExist, %IFile%
    Return, "Error: File not found"
  VarSetCapacity( buff, buffsz )
  If ISect=
    numchar:=DllCall("kernel32.dll\GetPrivateProfileString",Int,0,Int,0,Int,0,Str,buff,Int,buffsz,Str,IFile,Int)
  Else If IKey=
    numchar:=DllCall("kernel32.dll\GetPrivateProfileString",Str,ISect,Int,0,Int,0,Str,buff,Int,buffsz,Str,IFile,Int)
  Else
    numchar:=DllCall("kernel32.dll\GetPrivateProfileString",Str,ISect,Str,IKey,Int,0,Str,buff,Int,buffsz,Str,IFile,Int)   
  If (numchar > 1) {
    Loop {
    ahklen := StrLen(buff)
    If (ahklen < (numchar -1))
      DllCall("RtlFillMemory", UInt,(&buff+ahklen), UInt,1, UChar,Delim)
    Else
      break
    }
  }
  Return, buff
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 6th, 2006, 3:37 pm 
Offline

Joined: September 2nd, 2004, 1:08 am
Posts: 124
Location: Sunnyvale
This is what I was using: msgbox,% "Key Names: " . buff
...which does not work...
msgbox,Key Names: %buff%
... works fine...
Do we have a bug here?

_________________
I am he of whom he speaks!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 6th, 2006, 4:36 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Add "StringReplace buff, buff, `n, `r`n, All". It looks like in expressions `n is not enough for a new line.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 6th, 2006, 4:50 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
You can use the CharChange function below, which is slower, but can replace a char with an arbitrary string.
Code:
i = 10000
VarSetCapacity( buff, i )

; Return Key names
numchars:=DllCall("kernel32.dll\GetPrivateProfileString",Str,"HotKeys"
   ,Int,0,Str,"???",Str,buff,Int,i,Str,"c:\t\AutoHotKey\SKey.ini",Int)
msgbox % "Key Names: " CharChange(buff, 0, "`r`n", numchars)

CharChange(ByRef Buf, Ch, Str, Len=0) { ; In Buf all char of code Ch is replaced with Str
   m := VarSetCapacity(Buf)             ; Buf := CharChange(Buf, 0, "`r`n"): Nul -> new line
   If (Len < 1 or Len > m)
       Len = %m%
   Loop %Len%
      If (*(&Buf+A_Index-1) = Ch)
           out = %out%%Str%
      Else out:= out Chr(*(&Buf+A_Index-1))
   Return  out
}


Last edited by Laszlo on April 6th, 2006, 5:08 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 6th, 2006, 5:00 pm 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2545
Using the function I posted above:

Code:
MsgBox, % IniReadEx("C:\a.ini", "HotKeys" )


or change the file name, section, etc... for the file you are using...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 6th, 2006, 5:21 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
@corrupt: Your specialized version of StringReplace suffers from the same problem: if you set the delimiter character code to 13 (`n), it won't always be recognized as new line. With your default pipe "|" the problem remains hidden, everything is in one line. If some of your key names contain pipe characters, you are out of luck. `n is safer, because it cannot be part of a key name or value.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 34 posts ]  Go to page 1, 2, 3  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 14 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group