IDE Plugin sample based on HOOK

Share your advanced PureBasic knowledge/code with the community.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

IDE Plugin sample based on HOOK

Post by eddy »

question from: http://www.purebasic.fr/english/viewtopic.php?t=30640
1- the program ( hook installer )
2- the library ( hook callback ) <--- there's only 1 ProcedureDLL in this one.
This example is usefull for autostart-plugin.


MyHookInstaller.pb ----> MyHookInstaller.exe

Code: Select all

Global PB = Val(GetEnvironmentVariable("PB_TOOL_MainWindow"))  
If Not PB : End : EndIf 

Procedure CreateApplicationSharedVariable(name$,Value)
  fm=CreateFileMapping_($FFFFFFFF,0,#PAGE_READWRITE,0,1024,@name$) 
  If fm And fm <> #INVALID_HANDLE_VALUE 
    PokeS(MapViewOfFile_(fm,#FILE_MAP_WRITE,0,0,0) ,Str(Value)) 
    ProcedureReturn 1
  EndIf 
EndProcedure 
Procedure CreateHook(libraryName$)
  If OpenLibrary(0,libraryName$) And ExamineLibraryFunctions(0) And NextLibraryFunction()
    hookFunc = LibraryFunctionAddress() 
    hookLib = LibraryID(0)
    hookThread = GetWindowThreadProcessId_(PB,0)
    hook = SetWindowsHookEx_(#WH_CALLWNDPROCRET,hookFunc,hookLib,hookThread )   
    ProcedureReturn hook  
  EndIf  
EndProcedure 

MyHookInstallerWindow  = OpenWindow(1,600,600,100,100,"PB _Hook_Installer",#PB_Window_Invisible )
ApplicationSharedVariable  = CreateApplicationSharedVariable("PB_Hook_MyHookInstallerWindow",MyHookInstallerWindow)        
hook     = CreateHook("MyHookLibrary.dll")    

If Not hook : MessageRequester("Error !","No Hook !"):End :EndIf 
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

If ApplicationSharedVariable       : CloseHandle_(ApplicationSharedVariable)       : EndIf
If hook         : UnhookWindowsHookEx_(hook) : EndIf 
If IsLibrary(0) : CloseLibrary(0) : EndIf 
End 

MyHookLibrary.pb ---------> MyHookLibrary.dll

Code: Select all

Global Sci
Global PB
Global TB
Global TBNewButton.TBBUTTON 
Global MyHookInstallerWindow 

;{ Utils
Macro CloseWindowNow(win)
  PostMessage_(win,#WM_CLOSE,0,0)
EndMacro
Macro Scintilla(command,wParam=0 ,lParam=0 ) 
  SendMessage_(Sci,command,wParam,lParam) 
EndMacro
Procedure ReadApplicationSharedVariable(name.s)   
  fm = CreateFileMapping_($FFFFFFFF,0,#PAGE_READWRITE,0,1024,@name) 
  If fm And fm <> #INVALID_HANDLE_VALUE 
    Value=Val(PeekS(MapViewOfFile_(fm,#FILE_MAP_WRITE,0,0,0) ))
    CloseHandle_(fm)
    ProcedureReturn Value   
  EndIf  
EndProcedure 
Procedure GetToolbar(win,arrow=#True)
  Protected toolbar = FindWindowEx_(win, 0, "ToolbarWindow32", 0) 
  #TB_SETEXTENDEDSTYLE=$400+84 
  #TB_GETEXTENDEDSTYLE=$400+85  
  #TBSTYLE_EX_DRAWDDARROWS=$1 
  
  If arrow
    Protected exstyle = SendMessage_(toolbar,#TB_GETEXTENDEDSTYLE,0,0) | #TBSTYLE_EX_DRAWDDARROWS   
    SendMessage_(toolbar,#TB_SETEXTENDEDSTYLE,0,exstyle)    
  EndIf 
  ProcedureReturn toolbar
EndProcedure
Procedure GetToolbarNewButton(toolbar, *button.TBBUTTON, checked=#False,arrow=#False) 
  Protected posLast = SendMessage_(toolbar,#TB_BUTTONCOUNT,0,0)-1   
  Protected pos=0
  Protected idCommand=-1
  
  ;get button image
  ;#Picture=0
  ;Protected toolbarIcons=SendMessage_(toolbar,#TB_GETIMAGELIST,0,0) 
  ;CatchImage(#Picture, ?toolbarIcons) 
  ;iBitmap = ImageList_AddMasked_(toolbarIcons, ImageID(#Picture), RGB(255, 0, 255)) 
  
  ;get button command id
  For pos = 0 To posLast
    SendMessage_(toolbar,#TB_GETBUTTON,pos,*button)     
    If (idCommand < *button\idCommand )
      idCommand=*button\idCommand+1
    EndIf
  Next  
  
  ;insert button
  #TBSTYLE_DROPDOWN=$8    
  #BTNS_WHOLEDROPDOWN = $80     
  If arrow   : *button\fsStyle | #TBSTYLE_DROPDOWN | #BTNS_WHOLEDROPDOWN : EndIf
  If checked : *button\fsState | #TBSTATE_CHECKED : EndIf
  *button\fsStyle & ~#TBSTYLE_SEP  
  *button\iBitmap=iBitmap
  *button\idCommand=idCommand 
  *button\iString=posLast+1
  SendMessage_(toolbar,#TB_INSERTBUTTON,posLast+1,*button) 
  
  ProcedureReturn 1
EndProcedure
Procedure FreeToolbarNewButton(toolbar,*button.TBBUTTON)
  SendMessage_(toolbar,#TB_DELETEBUTTON,*button\iString,0)  
EndProcedure 
;} Utils

Procedure hookEditorAddon()  
  ; *****************
  ; toolbar button
  ; *****************    
  
  TB=GetToolbar(PB)
  GetToolbarNewButton(TB,TBNewButton.TBBUTTON,#False,#True)
  
  
  ; *****************
  ; popup menu 
  ; *****************
  
  Enumeration #PB_Compiler_EnumerationValue  
    #PopupMenu
    #MenuStop
  EndEnumeration 
  
  CreatePopupMenu(#PopupMenu)
  MenuItem(#MenuStop,"Stop...") 

EndProcedure
Procedure hookClose()
  If MyHookInstallerWindow 
    FreeMenu(#PopupMenu) 
    FreeToolbarNewButton(TB,TBNewButton)
    CloseWindowNow(MyHookInstallerWindow) 
  EndIf 
EndProcedure
Procedure hookFocus(code,focusedWindow)         
  Select code
    Case #SCEN_SETFOCUS 
      Sci=focusedWindow
    Case #SCEN_KILLFOCUS
      Sci=0
    Default 
      ProcedureReturn 0
  EndSelect
  ProcedureReturn 1
EndProcedure 
Procedure  hookToolbar(*TbMsg.NMTOOLBAR)
  #TBN_DROPDOWN=-710  
  #TPM_RETURNCMD=$100
  #TPM_NONOTIFY=$80 
  
  If *TbMsg\hdr\code = #TBN_DROPDOWN 
    Protected pt.POINT
    pt\x=*TbMsg\rcButton\left
    pt\y=*TbMsg\rcButton\bottom
    MapWindowPoints_(TB,0,@pt, 1); 
    EventMenu =TrackPopupMenu_(MenuID(#PopupMenu),#TPM_LEFTALIGN | #TPM_RETURNCMD | #TPM_NONOTIFY ,pt\x,pt\y,0,PB,0 )
    Select EventMenu
      Case #MenuStop 
        hookClose()
    EndSelect
  EndIf
EndProcedure
ProcedureDLL hook(code.l, wParam.l, lParam.l) 
  Structure MyCWPRETSTRUCT 
    lResult.l 
    lParam.l 
    wParam.l 
    message.l 
    hwnd.l 
  EndStructure   
  *myInfo.MyCWPRETSTRUCT = lParam  
  
  Select *myInfo\message        
    Case #WM_CLOSE 
      If PB And *myInfo\hwnd=PB
        hookClose()
      EndIf
    Case #WM_COMMAND         
      code=PeekW(@*myInfo\wParam +2)
      focus=*myInfo\lParam 
      hookFocus(code,focus)          
    Case #WM_NOTIFY
      *msg.NMHDR =*myInfo\lParam 
      code        =*msg\code
      hwndFrom    =*msg\hwndFrom
      idFrom      =*msg\idFrom
      
      If MyHookInstallerWindow=0    
        MyHookInstallerWindow = ReadApplicationSharedVariable("PB_Hook_MyHookInstallerWindow") 
        PB =*myInfo\hwnd
        hookEditorAddon() 
      EndIf
      
      If Sci And hwndFrom = Sci
        ;*SciMsg.SCNotification = *myInfo\lParam
        ;hookLexer(*SciMsg)
      EndIf   
      
      If TB And hwndFrom = TB
        *TbMsg.NMTOOLBAR =  *myInfo\lParam
        hookToolbar(*TbMsg) 
      EndIf      
  EndSelect 
  
  ProcedureReturn CallNextHookEx_(@hook(), code, wParam, lParam)    
EndProcedure

;DataSection 
;toolbarIcons: IncludeBinary("Icon16x16.bmp") 
;EndDataSection 
Last edited by eddy on Sat Jan 26, 2008 4:06 pm, edited 13 times in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post by superadnim »

Hi eddy, am I missing the point or the second source isn't showing up?.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

Ive not finished to write my post
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post by superadnim »

:? Thanks, I'll wait :lol:
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

[Finished ]
i fixed a problem
I can't make it simplier...

But there's always two problems or missing features :
- Any updates from Editor Preference Panel could destroy the new plugin toolbar button
- There's no single instance control ( you can open this plugin several times )
Last edited by eddy on Sat Jan 26, 2008 3:43 pm, edited 4 times in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

maybe the way your hooking?
Post Reply