Page 1 of 1

Start Menu requester

Posted: Sun Oct 17, 2010 1:10 pm
by Mistrel
I wanted something a little fancier than your run of the mill input requester so I put this together:

It makes used of the CreateAlignedStringGadget function I've posted as well:
http://www.purebasic.fr/english/viewtop ... 30#p336730

Image Image Image

Code: Select all

Procedure.s StartMenuRequester(Value.s, hParent=0)
  Protected NonClientMetrics.NONCLIENTMETRICS
  Protected *GrpIconDir.GRPICONDIR
  Protected Flags
  Protected WindowID
  Protected StringGadget
  Protected ButtonOk
  Protected ButtonCancel
  Protected hFont
  Protected hLib
  Protected LibID
  Protected *IconImage.ICONIMAGE
  Protected IconID
  Protected ImageIcon
  Protected InvalidChars.s
  Protected Event
  Protected FolderName.s
  Protected IsInvalid
  Protected i
  Protected n
  Protected lPEB.i
  Protected lOSMa.i
  Protected lOSMi.i
  Protected lOSPlat.i
  Protected OSVersion
  Protected BitCount
  Protected IsThemeActive
  Static hIcon
  Static Ptr
  
  Flags=#PB_Window_WindowCentered
  If Not IsWindow_(hParent)
    Flags=#PB_Window_ScreenCentered
  EndIf
  
  WindowID=OpenWindow(#PB_Any,0,0,246,83,"Specify Start Menu Folder",Flags|#PB_Window_TitleBar,hParent)
  
  If Not WindowID
    ProcedureReturn ""
  EndIf
  
  StringGadget=CreateAlignedStringGadget(#PB_Any,56,13,178,22,Value.s)
  ButtonOk=ButtonGadget(#PB_Any,78,48,75,23,"OK")
  ButtonCancel=ButtonGadget(#PB_Any,159,48,75,23,"Cancel")
  
  ;/ Get the default system message window font
  NonClientMetrics\cbSize=SizeOf(NONCLIENTMETRICS)
  SystemParametersInfo_(#SPI_GETNONCLIENTMETRICS,SizeOf(NONCLIENTMETRICS),@NonClientMetrics,0)
  hFont=CreateFontIndirect_(@NonClientMetrics\lfMessageFont)
  
  SetGadgetFont(ButtonOk,hFont)
  SetGadgetFont(ButtonCancel,hFont)
  
  If Not StringGadget Or Not ButtonOk Or Not ButtonCancel
    ProcedureReturn ""
  EndIf
  
  If Not hIcon And Not *GrpIconDir
    hLib=LoadLibraryEx_("shell32.dll",0,#LOAD_LIBRARY_AS_DATAFILE)
    *GrpIconDir=LoadResource_(hLib,FindResource_(hLib,40,#RT_GROUP_ICON))
  EndIf
  
  ;/ Get the OS version
  lPEB=PeekI(NtCurrentTeb_()+$30)
  lOSMa=PeekI(lPEB+$A4)
  lOSMi=PeekI(lPEB+$A8)
  lOSPlat=PeekI(lPEB+$B0)
  OSVersion=Val(Str(lOSPlat)+Str(lOSMa)+Str(lOSMi))
  
  ;/ Is XP/Vista themes active?
  If Not Ptr
    LibID=OpenLibrary(#PB_Any,"uxtheme.dll")
    Ptr=GetFunction(LibID,"IsThemeActive")
  EndIf
  
  If Ptr
    IsThemeActive=CallFunctionFast(Ptr)
  EndIf
  
  ;/ If the OS is less than vista and the user is not using the XP theme then use the old
  ;/ style start menu icon
  If OSVersion<260 And Not IsThemeActive
    BitCount=4
  Else
    BitCount=32
  EndIf
  
  If *GrpIconDir
    For i=0 To *GrpIconDir\idCount
      If *GrpIconDir\idEntries[i]\wBitCount=BitCount And *GrpIconDir\idEntries[i]\bHeight=32
        IconID=*GrpIconDir\idEntries[i]\nID
        Break
      EndIf
    Next i
    
    *IconImage=LoadResource_(hLib,FindResource_(hLib,IconID,#RT_ICON))
    
    If *IconImage
      hIcon=CreateIconFromResource_(*IconImage,*IconImage\icHeader\biBitCount,1,$00030000)
    EndIf
  EndIf
  
  If hLib
    FreeLibrary_(hLib)
  EndIf
  
  If hIcon
    ImageIcon=ImageGadget(#PB_Any,13,13,32,32,hIcon)
  EndIf
  
  InvalidChars.s="\/:*?<>|"+#DQUOTE$
  
  Repeat
    Event=WaitWindowEvent(1)
    
    FolderName.s=GetGadgetText(StringGadget)
    
    ;/ Validate folder characters
    IsInvalid=#False
    For i=1 To Len(FolderName.s)
      For n=1 To Len(InvalidChars.s)
        If Mid(FolderName.s,i,1)=Mid(InvalidChars.s,n,1)
          IsInvalid=#True
        EndIf
      Next n
    Next i
    
    If Not Trim(FolderName.s) Or IsInvalid
      DisableGadget(ButtonOk,#True)
    Else
      DisableGadget(ButtonOk,#False)
    EndIf
    
    If Event=#PB_Event_Gadget
      Select EventGadget()
        Case ButtonOk
          Break
        Case ButtonCancel
          FolderName.s=""
          Break
      EndSelect
    EndIf
  ForEver
  
  FreeAlignedStringGadget(StringGadget)
  FreeGadget(ButtonOk)
  FreeGadget(ButtonCancel)
  
  If IsGadget(ImageIcon)
    FreeGadget(ImageIcon)
  EndIf
  
  CloseWindow(WindowID)
  
  ProcedureReturn Trim(FolderName.s)
EndProcedure

Re: Start Menu requester

Posted: Sun Oct 17, 2010 3:06 pm
by HAnil
Hi
CreateAlignedStringGadget funtion is not found !

Re: Start Menu requester

Posted: Sun Oct 17, 2010 3:29 pm
by TomS
HAnil wrote:Hi
CreateAlignedStringGadget funtion is not found !
Look the thread he linked above. There are the two procedures for CreateAlignedStringGadget().

It's a nice looking requester, but what is a "startmenu requester" good for?
Maybe if you change the title to "InputRequester with Icon", more people will find this thread ;)

Re: Start Menu requester

Posted: Sun Oct 17, 2010 5:04 pm
by Mistrel
There is a dialog in my installer you can bring up to change the start menu name. :roll:

Re: Start Menu requester

Posted: Mon Oct 18, 2010 12:26 am
by iostream
IMA at the following line:

Code: Select all

For i=0 To *GrpIconDir\idCount
But a nice align procedure :D

Re: Start Menu requester

Posted: Mon Oct 18, 2010 3:27 am
by Mistrel
iostream wrote:IMA at the following line:

Code: Select all

For i=0 To *GrpIconDir\idCount
But a nice align procedure :D
I wasn't quite sure about this one. Try uncommenting:

Code: Select all

If Not *GrpIconDir / EndIf
Surrounding this block:

Code: Select all

Lib=LoadLibraryEx_("shell32.dll",0,#LOAD_LIBRARY_AS_DATAFILE)
*GrpIconDir=LoadResource_(Lib,FindResource_(Lib,40,#RT_GROUP_ICON))
 FreeLibrary_(Lib)
I wasn't sure if the resource would still be valid after I freed the library. Maybe it isn't.

Let me know if that fixes it and I'll post some updated code.

Also, what OS/compiler are you using? I did not test this on a PB x64.

Re: Start Menu requester

Posted: Mon Oct 18, 2010 4:07 am
by Mistrel
I've fixed a couple of bugs in the original source. Try again now.

I also changed it so that the icon defaults to the 9x variant if the OS is less than vista with UX themes disabled.