CLCL plugin (?)

Just starting out? Need help? Post your questions and find answers here.
AZJIO
Addict
Addict
Posts: 2158
Joined: Sun May 14, 2017 1:48 am

CLCL plugin (?)

Post by AZJIO »

Can anyone help me make a plugin for CLCL?

Here you can view the CLCLPlugin folder and the CLCLPlugin\tool_test\tool_test.c file.

CLCLPlugin.pbi (using Header Converter.exe). But I don't understand the meaning of #WM_APP

Code: Select all

#BUF_SIZE = 256
#WM_GET_VERSION = (#WM_APP+100)
#WM_GET_WORKPATH = (#WM_APP+101)
#WM_GET_CLIPBOARD_WATCH = (#WM_APP+102)
#WM_SET_CLIPBOARD_WATCH = (#WM_APP+103)
#WM_GET_FORMAT_ICON = (#WM_APP+104)
#WM_ENABLE_ACCELERATOR = (#WM_APP+105)
#WM_REGIST_HOTKEY = (#WM_APP+106)
#WM_UNREGIST_HOTKEY = (#WM_APP+107)
#WM_OPTION_SHOW = (#WM_APP+200)
#WM_OPTION_GET = (#WM_APP+201)
#WM_OPTION_LOAD = (#WM_APP+202)
#WM_OPTION_SAVE = (#WM_APP+203)
#WM_HISTORY_CHANGED = (#WM_APP+300)
#WM_HISTORY_GET_ROOT = (#WM_APP+301)
#WM_HISTORY_LOAD = (#WM_APP+302)
#WM_HISTORY_SAVE = (#WM_APP+303)
#WM_REGIST_CHANGED = (#WM_APP+350)
#WM_REGIST_GET_ROOT = (#WM_APP+351)
#WM_REGIST_LOAD = (#WM_APP+352)
#WM_REGIST_SAVE = (#WM_APP+353)
#WM_ITEM_TO_CLIPBOARD = (#WM_APP+400)
#WM_ITEM_CREATE = (#WM_APP+401)
#WM_ITEM_COPY = (#WM_APP+402)
#WM_ITEM_FREE = (#WM_APP+403)
#WM_ITEM_FREE_DATA = (#WM_APP+404)
#WM_ITEM_CHECK = (#WM_APP+405)
#WM_ITEM_TO_BYTES = (#WM_APP+406)
#WM_ITEM_FROM_BYTES = (#WM_APP+407)
#WM_ITEM_TO_FILE = (#WM_APP+408)
#WM_ITEM_FROM_FILE = (#WM_APP+409)
#WM_ITEM_GET_PARENT = (#WM_APP+410)
#WM_ITEM_GET_FORMAT_TO_ITEM = (#WM_APP+411)
#WM_ITEM_GET_PRIORITY_HIGHEST = (#WM_APP+412)
#WM_ITEM_GET_TITLE = (#WM_APP+413)
#WM_ITEM_GET_OPEN_INFO = (#WM_APP+414)
#WM_ITEM_GET_SAVE_INFO = (#WM_APP+415)
#WM_VIEWER_SHOW = (#WM_APP+500)
#WM_VIEWER_GET_HWND = (#WM_APP+501)
#WM_VIEWER_GET_MAIN_HWND = (#WM_APP+504)
#WM_VIEWER_GET_SELECTION = (#WM_APP+502)
#WM_VIEWER_SELECT_ITEM = (#WM_APP+503)
#TYPE_DATA = 0
#TYPE_ITEM = 1
#TYPE_FOLDER = 2
#TYPE_ROOT = 3
#CALLTYPE_MENU = 1
#CALLTYPE_VIEWER = 2
#CALLTYPE_VIEWER_OPEN = 4
#CALLTYPE_VIEWER_CLOSE = 8
#CALLTYPE_ADD_HISTORY = 16
#CALLTYPE_ITEM_TO_CLIPBOARD = 32
#CALLTYPE_START = 64
#CALLTYPE_END = 128
#CALLTYPE_MENU_COPY_PASTE = 256
#CALLTYPE_HISTORY = 512
#CALLTYPE_REGIST = 1024
#TOOL_ERROR = 0
#TOOL_SUCCEED = 1
#TOOL_CANCEL = 2
#TOOL_DATA_MODIFIED = 4

Structure FORMAT_GET_INFO
  struct_size.DWORD
  format_name.TCHAR[#BUF_SIZE]
  func_header.TCHAR[#BUF_SIZE]
  comment.TCHAR[#BUF_SIZE]
EndStructure

Structure TOOL_GET_INFO
  struct_size.DWORD
  title.TCHAR[#BUF_SIZE]
  func_name.TCHAR[#BUF_SIZE]
  cmd_line.TCHAR[#BUF_SIZE]
  call_type.l
EndStructure

Structure TOOL_EXEC_INFO
  struct_size.DWORD
  call_type.l
 *cmd_line.TCHAR
  lParam.LPARAM
EndStructure

Structure DATA_INFO
  struct_size.DWORD
  type.l
 *title.TCHAR
 *format_name.TCHAR
  format_name_hash.l
  format.UINT
  Data.HANDLE
  size.DWORD
  modified.FILETIME
 *window_name.TCHAR
 *plugin_string.TCHAR
  plugin_param.LPARAM
 *menu_title.TCHAR
  free_title.BOOL
  menu_icon.HICON
  free_icon.BOOL
  menu_bitmap.HBITMAP
  free_bitmap.BOOL
  menu_bmp_width.l
  menu_bmp_height.l
  param1.LPARAM
  param2.LPARAM
 *child.DATA_INFO
 *Next.DATA_INFO
  hkey_id.l
  op_modifiers.UINT
  op_virtkey.UINT
  op_paste.l
EndStructure

Structure TOOL_DATA_INFO
  struct_size.DWORD
 *di.DATA_INFO
 *child.TOOL_DATA_INFO
 *Next.TOOL_DATA_INFO
EndStructure
My example

Code: Select all

XIncludeFile "CLCLPlugin.pbi"

ProcedureDLL AttachProcess(Instance)
	hInst = Instance
; 	dll_initialize() ; отключил инициализацию, так как там в принципе поиск рабочей папки CLCL и ini.
EndProcedure

ProcedureDLL DetachProcess(Instance)
; 	dll_uninitialize() ; отключил деинициализацию, так как она возвращает 1 в static BOOL (мы не знаем что это такое)
EndProcedure

ProcedureDLL AttachThread(Instance)
EndProcedure

ProcedureDLL DetachThread(Instance)
EndProcedure


ProcedureDLL get_tool_info_w(hWnd, index, tgi.TOOL_GET_INFO)
	Select index
		Case 0
			tgi\title = "Conv" ; загрузить из ресурсов, так есть возможность легко и безболезненно поменять.
			tgi\func_name = "Conv"
			tgi\cmd_line = ""
			ProcedureReturn 1
; 		Case
	EndSelect
	ProcedureReturn 0
EndProcedure


; ProcedureDLL dll_initialize()
	; 	Дескриптор NULL вместо hInst указывает на поиск пути к исполняемому файлу вместо текущей библиотеки dll.

	; 	найдите файл tool_clip.ini в той же папке, что и clcl.ini, кроме того clcl.exe

; 	Для режима выпуска (не переносимого приложения) установите ini_path в ту же папку, что и %LOCALAPPDATA%\CLCL\clcl.ini
; 	чтобы у нас был доступ на запись.
; 	Смотрите C:\home\wilf\Projects\Clcl.cvs\main.c строка 2234 и далее

; 	TODO: скопировать из старого расположения в dll-папку
; EndProcedure


; ProcedureDLL dll_uninitialize()
; 	ProcedureReturn 1
; EndProcedure


ProcedureDLL Conv(hWnd, tei.TOOL_EXEC_INFO, tgi.TOOL_DATA_INFO)
	If tdi = 0
		ProcedureReturn #TOOL_SUCCEED
	EndIf

	di.DATA_INFO = tdi\di
	If di = 0 Or (di\type <> TYPE_ITEM And di\type <> TYPE_DATA)
		ProcedureReturn #TOOL_ERROR
	EndIf

	SendMessage(hWnd, WM_ITEM_TO_CLIPBOARD, 0, @"проверка")
	ProcedureReturn #TOOL_SUCCEED
EndProcedure
User avatar
mk-soft
Always Here
Always Here
Posts: 6233
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: CLCL plugin (?)

Post by mk-soft »

My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
AZJIO
Addict
Addict
Posts: 2158
Joined: Sun May 14, 2017 1:48 am

Re: CLCL plugin (?)

Post by AZJIO »

Download a_tool.dll + Source + Readme.txt
I got the function names by replacing the ".a" character type in the array strings with the ".u" type.
Now everything works, and the "Conv" function is executed.
An important nuance: the app is only 32-bit

CLCLPlugin.pbi

Code: Select all

; BOOL -> i
; TCHAR -> u
; DWORD -> l
; *var - у указателя удалён тип (a)

#BUF_SIZE = 256
#WM_GET_VERSION = (#WM_APP+100)
#WM_GET_WORKPATH = (#WM_APP+101)
#WM_GET_CLIPBOARD_WATCH = (#WM_APP+102)
#WM_SET_CLIPBOARD_WATCH = (#WM_APP+103)
#WM_GET_FORMAT_ICON = (#WM_APP+104)
#WM_ENABLE_ACCELERATOR = (#WM_APP+105)
#WM_REGIST_HOTKEY = (#WM_APP+106)
#WM_UNREGIST_HOTKEY = (#WM_APP+107)
#WM_OPTION_SHOW = (#WM_APP+200)
#WM_OPTION_GET = (#WM_APP+201)
#WM_OPTION_LOAD = (#WM_APP+202)
#WM_OPTION_SAVE = (#WM_APP+203)
; константы действий над историей
#WM_HISTORY_CHANGED = (#WM_APP+300)
#WM_HISTORY_GET_ROOT = (#WM_APP+301)
#WM_HISTORY_LOAD = (#WM_APP+302)
#WM_HISTORY_SAVE = (#WM_APP+303)
; константы действий над избранным
#WM_REGIST_CHANGED = (#WM_APP+350)
#WM_REGIST_GET_ROOT = (#WM_APP+351)
#WM_REGIST_LOAD = (#WM_APP+352)
#WM_REGIST_SAVE = (#WM_APP+353)
; константы действий над пунктами:
#WM_ITEM_TO_CLIPBOARD = (#WM_APP+400)
#WM_ITEM_CREATE = (#WM_APP+401)
#WM_ITEM_COPY = (#WM_APP+402)
#WM_ITEM_FREE = (#WM_APP+403)
#WM_ITEM_FREE_DATA = (#WM_APP+404)
#WM_ITEM_CHECK = (#WM_APP+405)
#WM_ITEM_TO_BYTES = (#WM_APP+406)
#WM_ITEM_FROM_BYTES = (#WM_APP+407)
#WM_ITEM_TO_FILE = (#WM_APP+408)
#WM_ITEM_FROM_FILE = (#WM_APP+409)
#WM_ITEM_GET_PARENT = (#WM_APP+410)
#WM_ITEM_GET_FORMAT_TO_ITEM = (#WM_APP+411)
#WM_ITEM_GET_PRIORITY_HIGHEST = (#WM_APP+412)
#WM_ITEM_GET_TITLE = (#WM_APP+413)
#WM_ITEM_GET_OPEN_INFO = (#WM_APP+414)
#WM_ITEM_GET_SAVE_INFO = (#WM_APP+415)
; константы действий над  главным окном
#WM_VIEWER_SHOW = (#WM_APP+500)
#WM_VIEWER_GET_HWND = (#WM_APP+501)
#WM_VIEWER_GET_MAIN_HWND = (#WM_APP+504)
#WM_VIEWER_GET_SELECTION = (#WM_APP+502)
#WM_VIEWER_SELECT_ITEM = (#WM_APP+503)
#TYPE_DATA = 0
#TYPE_ITEM = 1
#TYPE_FOLDER = 2
#TYPE_ROOT = 3
; тип вызова, в настройке на вкладке "Плагины" при клике на плагине вылетает окно и внизу куча галочек
; структура *tgi\call_type = показывает какие галочки будут отмечены.
#CALLTYPE_MENU = 1
#CALLTYPE_VIEWER = 2
#CALLTYPE_VIEWER_OPEN = 4
#CALLTYPE_VIEWER_CLOSE = 8
#CALLTYPE_ADD_HISTORY = 16
#CALLTYPE_ITEM_TO_CLIPBOARD = 32
#CALLTYPE_START = 64
#CALLTYPE_END = 128
#CALLTYPE_MENU_COPY_PASTE = 256
#CALLTYPE_HISTORY = 512
#CALLTYPE_REGIST = 1024

#TOOL_ERROR = 0
#TOOL_SUCCEED = 1
#TOOL_CANCEL = 2
#TOOL_DATA_MODIFIED = 4

Structure FORMAT_GET_INFO
  struct_size.l
  format_name.u[#BUF_SIZE]
  func_header.u[#BUF_SIZE]
  comment.u[#BUF_SIZE]
EndStructure

Structure TOOL_GET_INFO
  struct_size.l
  title.u[#BUF_SIZE]
  func_name.u[#BUF_SIZE]
  cmd_line.u[#BUF_SIZE]
  call_type.l
EndStructure

; структура отправляется в каждую пользовательскую функцию
Structure TOOL_EXEC_INFO
  struct_size.l
  call_type.l
 *cmd_line
  lParam.i
EndStructure

Structure DATA_INFO
  struct_size.l
  type.l
 *title
 *format_name
  format_name_hash.l
  format.l
  Data.i
  size.l
  modified.FILETIME
 *window_name
 *plugin_string
  plugin_param.i
 *menu_title
  free_title.i
  menu_icon.i
  free_icon.i
  menu_bitmap.i
  free_bitmap.i
  menu_bmp_width.l
  menu_bmp_height.l
  param1.i
  param2.i
 *child.DATA_INFO
 *next.DATA_INFO
  hkey_id.l
  op_modifiers.l
  op_virtkey.l
  op_paste.l
EndStructure

; структура отправляется в каждую пользовательскую функцию
Structure TOOL_DATA_INFO
  struct_size.l
 *di.DATA_INFO
 *child.TOOL_DATA_INFO
 *Next.TOOL_DATA_INFO
EndStructure
.

Code: Select all

EnableExplicit

Global hInst

XIncludeFile "CLCLPlugin.pbi"

ProcedureDLL AttachProcess(Instance)
	hInst = Instance
; 	dll_initialize() ; отключил инициализацию, так как там в принципе поиск рабочей папки CLCL и ini.
EndProcedure

ProcedureDLL DetachProcess(Instance)
; 	dll_uninitialize() ; отключил деинициализацию, так как она возвращает 1 в static BOOL (мы не знаем что это такое)
EndProcedure

ProcedureDLL AttachThread(Instance)
EndProcedure

ProcedureDLL DetachThread(Instance)
EndProcedure


ProcedureDLL FindTitle(hWnd, *tei.TOOL_EXEC_INFO, *tdi.TOOL_DATA_INFO)
	Protected *di.DATA_INFO
	Protected buffer$ = Space(256)
	Protected tmp$

; 	If *tdi = 0
; 		ProcedureReturn #TOOL_SUCCEED
; 	EndIf
; 
; 	If *tdi\di\struct_size = 0 Or (*tdi\di\type <> #TYPE_ITEM And *tdi\di\type <> #TYPE_DATA)
; 		ProcedureReturn #TOOL_ERROR
; 	EndIf

	
	tmp$ = InputRequester("find", "enter the text:", "")
; 	OutputDebugString_("1 - " + tmp$)
	If Not Asc(tmp$)
		ProcedureReturn #TOOL_SUCCEED
	EndIf
; 	OutputDebugString_("2 - " + tmp$)
	
	*di = SendMessage_(hWnd, #WM_HISTORY_GET_ROOT, 0, 0) ; получаем корень истории
	*di = *di\child ; текущий первый элемент
; 	*di = *tdi\di ; это кликнутый в истории (передаётся в функцию как параметр)
	While *di
		; 		OutputDebugString_(Str(*di\type)) ; тип #TYPE_FOLDER и т.д., но всё равно нет возможности пробежаться по папкам.
		If *di\type = #TYPE_FOLDER
			Break
		EndIf
		; получает пункт меню истории (кроме вложенных в папки)
		SendMessage_(hWnd, #WM_ITEM_GET_TITLE, @buffer$, *di)
; 		OutputDebugString_("3 - " + buffer$)
		If Asc(buffer$) And FindString(buffer$, tmp$, 1, #PB_String_NoCase)
			; OutputDebugString_("4 - " + buffer$)
			SendMessage_(hWnd, #WM_ITEM_TO_CLIPBOARD, 0, *di) ; вставляет пункт истории в буфер обмена
			SendMessage_(hWnd, #WM_HISTORY_CHANGED, 0, 0)	  ; обновить историю
			Break ; даже если не будет Break, он всё равно остановится тут, видимо предыдущие SendMessage влияют на это
		EndIf
		*di = *di\next ; берём следующий элементов истории
	Wend
	
	ProcedureReturn #TOOL_SUCCEED
EndProcedure


ProcedureDLL get_tool_info_w(hWnd, index, *tgi.TOOL_GET_INFO)
	Select index
		Case 0
			PokeS(@*tgi\title, "FindTitle", -1, #PB_Unicode) ; загрузить из ресурсов, так есть возможность легко и безболезненно поменять.
			PokeS(@*tgi\func_name, "FindTitle")
			PokeS(@*tgi\cmd_line, "")
			*tgi\call_type = #CALLTYPE_MENU | #CALLTYPE_VIEWER
			ProcedureReturn 1
; 		Case
	EndSelect
	ProcedureReturn 0
EndProcedure
Post Reply