Here's the code I'm using to support WinAsm:
USE_DOCKING_WINDOWS equ TRUE


; -------------------------------------------------------------------------
; WinAsm addin support
; -------------------------------------------------------------------------

include \WinAsm\Inc\WAAddIn.inc

GetWAAddInData proto :DWORD,:DWORD
WAAddInLoad proto :DWORD,:DWORD
FrameWindowProc proto :DWORD,:DWORD,:DWORD,:DWORD
DockingProc proto :DWORD,:DWORD,:DWORD,:DWORD
WAAddInUnload proto

.const
ifdef USE_DOCKING_WINDOWS
sz DockingData
endif

szAddinsINI db "AddIns\WAAddIns.Ini",0

.data
AddInDockData DOCKINGDATA <offset szName,NODOCK,<30,30,180,134>,60,120,180,180>

.data?
pHandles dd ? ;Pointer to WinAsm handles

ifdef USE_DOCKING_WINDOWS
pOldProc dd ? ;Pointer to old window proc for docking window
endif

align DWORD
GetWAAddInData proc lpFriendlyName,lpDescription

invoke MoveMemory,lpFriendlyName,offset szName,sizeof szName
invoke MoveMemory,lpDescription,offset szDesc,sizeof szDesc
ret

GetWAAddInData endp

align DWORD
WAAddInLoad proc uses ebx pWinAsmHandles,features
local IsActiveChildMaximized:DWORD

ifdef USE_DOCKING_WINDOWS
movi fDocking,TRUE
endif
invoke ReadConfig,offset szAddinsINI
mov ebx,pWinAsmHandles
mov pHandles,ebx
push [ebx].HANDLES.hMain
pop hMain
invoke SendMessage,[ebx].HANDLES.hClient,WM_MDIGETACTIVE,0,addr IsActiveChildMaximized
mov eax,7 ;7 for AddIns menu
.if IsActiveChildMaximized
inc eax
.endIf
mov AddinMenu,$invoke(GetSubMenu,[ebx].HANDLES.hMenu,eax)
invoke GetMenuItemCount,eax
dec eax
.if zero?
invoke AppendMenu,AddinMenu,MF_SEPARATOR,0,0
.endif
mov AddinID,$invoke(SendMessage,[ebx].HANDLES.hMain,WAM_GETNEXTMENUID,0,0)
invoke AppendMenu,AddinMenu,MF_OWNERDRAW,eax,offset szMenuText
ifdef USE_DOCKING_WINDOWS
mov eax,WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_CHILD or STYLE_TWOLINESTITLE
.if fActive
or eax,WS_VISIBLE
push eax
invoke CheckMenuItem,AddinMenu,AddinID,MF_BYCOMMAND or MF_CHECKED
pop eax
.endif
mov hDocking,$invoke(SendMessage,hMain,WAM_CREATEDOCKINGWINDOW,eax,offset AddInDockData)
mov pOldProc,$invoke(SetWindowLong,eax,GWL_WNDPROC,offset DockingProc)
invoke SendMessage,hDocking,WM_CREATE,0,0
else
invoke CreateWorker
endif
xor eax,eax
ret

WAAddInLoad endp

align DWORD
WAAddInUnload proc

mov fActive,FALSE
mov eax,AddinPopup
ifdef USE_DOCKING_WINDOWS
.if fDocking
mov eax,hDocking
.endif
endif
.if eax != 0
invoke IsWindowVisible,eax
.if eax
inc fActive ;TRUE
.endif
ifdef USE_DOCKING_WINDOWS
invoke SendMessage,hDocking,WAM_DESTROYDOCKINGWINDOW,0,0
else
invoke SendMessage,AddinPopup,WM_DESTROY,0,0
endif
.endif
ifndef USE_DOCKING_WINDOWS
invoke PostThreadMessage,IdWorker,WM_QUIT,0,0
invoke WaitForSingleObject,hWorker,INFINITE
invoke CloseHandle,hWorker
endif
invoke GetMenuItemCount,AddinMenu
.if eax == 3
invoke DeleteMenu,AddinMenu,1,MF_BYPOSITION
.endIf
invoke DeleteMenu,AddinMenu,AddinID,MF_BYCOMMAND
invoke WriteConfig
xor eax,eax
ret

WAAddInUnload endp

align DWORD
FrameWindowProc proc hWin,uMsg,wParam,lParam
local iCode :DWORD

.if uMsg == WM_COMMAND
mov eax,wParam
and eax,not 10000h
.if eax == AddinID
ifdef USE_DOCKING_WINDOWS
invoke IsWindowVisible,hDocking
.if eax == FALSE
movi eax,SW_SHOW
.else
movi eax,SW_HIDE
.endif
invoke ShowWindow,hDocking,eax
else
invoke PostThreadMessage,IdWorker,WM_USER+100h,TRUE,0
endif
xor eax,eax
inc eax
ret
.endif
.endif
xor eax,eax
ret

FrameWindowProc endp

ifdef USE_DOCKING_WINDOWS
align DWORD
DockingProc proc hWin,uMsg,wParam,lParam
local rect:RECT

mov eax,uMsg
.switch eax

.case WM_SIZE
invoke GetWindowLong,hWin,0
.if eax != 0
invoke MoveMemory,offset AddInDockData,eax,sizeof DOCKINGDATA
.endif
invoke SendMessage,hWin,WAM_GETCLIENTRECT,0,addr rect
invoke MoveWindow,AddinPopup,0,0,rect.right,rect.bottom,TRUE
.break

.case WM_SHOWWINDOW
mov eax,wParam
shl eax,3
invoke CheckMenuItem,AddinMenu,AddinID,eax
.break

.case WM_CREATE
invoke CreateDialogParam,hInst,IDD_DIALOG2,hWin,offset DlgProc,0
.if eax != 0
invoke SendMessage,hWin,WAM_GETCLIENTRECT,0,addr rect
mov eax,rect.right
mov edx,rect.bottom
sub eax,rect.left
sub edx,rect.top
invoke MoveWindow,AddinPopup,rect.left,rect.top,eax,edx,TRUE
.else
invoke PostMessage,hWin,WAM_DESTROYDOCKINGWINDOW,0,0
.endif
xor eax,eax
ret

.case WM_DESTROY
invoke SetWindowLong,hWin,GWL_WNDPROC,pOldProc

.endswitch
invoke CallWindowProc,pOldProc,hWin,uMsg,wParam,lParam
ret

DockingProc endp
endif
Posted on 2003-10-30 16:10:36 by QvasiModo
Hi,

The problem seems to be here:


.case WM_SIZE

invoke GetWindowLong,hWin,0
.if eax != 0
invoke MoveMemory,offset AddInDockData,eax,sizeof DOCKINGDATA
.endif
invoke SendMessage,hWin,WAM_GETCLIENTRECT,0,addr rect
invoke MoveWindow,AddinPopup,0,0,rect.right,rect.bottom,TRUE
.break


Try this:

.case WM_SIZE
Invoke SendMessage,hAddIn,WAM_GETCLIENTRECT,0,ADDR Rect
MOV EAX,Rect.right
SUB EAX,Rect.left
MOV ECX,Rect.bottom
SUB ECX,Rect.top
Invoke MoveWindow,AddinPopup,Rect.left,Rect.top,EAX,ECX,TRUE
.break

PS1. I guess AddinPopup is your dialog handle.

PS2. Attached is a simple Add-In using a WS_CHILD dialog hosted in a docking window.

Regards,

akyprian
Posted on 2003-10-31 06:59:31 by akyprian
hi,

It could be interesting if the user could see the number and the constant name at the same time.
(maybe by adding the number in dec/hex inside the description).

Also it could be interesting if it could run without the window interface (in a tooltip injected inside sources windows or somekind of listbox).

h.
Posted on 2003-10-31 12:24:45 by hitchhikr
Still one more to fix... Once I got that one I'll post the new version.

@Akyprian:

Thanks for the tips! :) I had already catched up on the fact that the client rect of a docking window does not start at (0,0), but I forgot to change the code to handle WM_SIZE (I only changed WM_CREATE). I have also found another error in the dialog box procedure, and fixed it. So now it's almost working... Now for some reason the controls are not being resized properly. In fact they are not even shown :grin: unless I remove this code from the dialog box procedure:


.case WM_SIZE
.break .if wParam == SIZE_MINIMIZED
ifdef USE_DOCKING_WINDOWS
.if fDocking
invoke SendMessage,hWin,WAM_GETCLIENTRECT,0,addr rect
.else
invoke GetClientRect,hWin,addr rect
.endif
else
invoke GetClientRect,hWin,addr rect
endif
mov hEdit1,$invoke(GetDlgItem,hWin,IDC_EDIT1)
invoke GetDlgItem,hWin,IDC_COMBO1
invoke MoveWindow,eax,0,0,rect.right,rect.bottom,TRUE
lea edx,rect2
push edx
push hWin
invoke GetWindowRect,hEdit1,edx
call ScreenToClient
mov edx,rect.bottom
sub edx,rect2.top
.if sign?
neg edx
.endif
mov eax,rect.right
sub eax,rect.left
invoke SetWindowPos,hEdit1,0,0,0,eax,edx,SWP_NOMOVE or SWP_NOOWNERZORDER or SWP_NOZORDER
.break

So my bug must be here... weird because it's working for the other IDEs. :confused:

Must be a problem in the way I calculate the control's position from the client rect.


@hitchhikr:

Updated. Now the addin works as a modeless box in Chrome too. One thing though, the dialog box doesn't seem to be created on startup. When you close the IDE and WinErr was visible, next time you launch the IDE WinErr will show itself on startup. This seems to fail on Chrome... perhaps AddInLoad is called before the MDI frame window is created?

I have also implemented your first suggestion, I think it's a very good idea to show the error name and number besides it's description. :alright:

As for the second, I didn't understand it much... you mean like a tooltip that pops up when the user double-cliks on an error equate? (sorry for the dumb question).
Posted on 2003-11-02 15:29:41 by QvasiModo

Updated. Now the addin works as a modeless box in Chrome too. One thing though, the dialog box doesn't seem to be created on startup. When you close the IDE and WinErr was visible, next time you launch the IDE WinErr will show itself on startup. This seems to fail on Chrome... perhaps AddInLoad is called before the MDI frame window is created?


Being used within the AddIns menu, yours have a limited range (the range of a stand-alone tool) as the one that are provided with the distrib.
These addins are alive within a single session.

Other type of addins exist that can use AddInMenu as a configuration panel or something else (not mandatory).
These are primary designed to enhance the core interface of the IDE.


As for the second, I didn't understand it much... you mean like a tooltip that pops up when the user double-cliks on an error equate? (sorry for the dumb question).


Like when the user leave the mouse pointer on the name of an error constant (in a source) for a short period of time a toolip appears containing the description of that error.

example:



mov eax, ERROR_DIR_NOT_EMPTY


When the user leave the mouse pointer on the ERROR_DIR_NOT_EMPTY word, the description (with the number) pops up.

That's what i call an enhancment of the core interface of the IDE. But i might be done carefully because some other AddIns might want to display a value for other constants (not errors but some others).

Btw, i released an update where i removed a bug i found while checking AddInLoad (hMDI was empty).

h.
Posted on 2003-11-02 17:33:50 by hitchhikr
Hi Qvasimodo,

-There is no difference if the Docking Window is floating or docked. So you should always use WAM_GETCLIENTRECT to get its client rectangle.

-I attached a modified version to see how I would handle sizing (not optimized)

akyprian
Posted on 2003-11-03 00:30:39 by akyprian

Hi Qvasimodo,

-There is no difference if the Docking Window is floating or docked. So you should always use WAM_GETCLIENTRECT to get its client rectangle.

-I attached a modified version to see how I would handle sizing (not optimized)

akyprian

Yes, I know you should use always WAM_GETCLIENTRECT.
The fDocking flag only indicates if a docking window is in place (NOT if that window is locked). Remember that I'm sharing that code with the support for the other IDEs.
I'm taking a look at you second example anyway. :)
Posted on 2003-11-03 12:05:06 by QvasiModo
@hitchhikr: Mhm... it seems a bit complicated, specially thinking of other addins that might want to do something similar. Now I got what you mean, I've added it to my to do list, but first I'll get this version finished.
I'm also downloading the latest version of Chrome, maybe that hMDI bug was the cause of the addin not being launched on startup.
Posted on 2003-11-03 12:08:29 by QvasiModo
This is what I have so far (under development!)
Everything should work fine except under WinAsm, so please tell me of any bugs you might find.

EDIT: Attachment removed. Latest version at the beginning of this thread.
Posted on 2003-11-03 12:54:19 by QvasiModo
Since you're addin is returning ADDIN_FINISHED in the AddInLoad proc chrome will run AddInUnload right away
but it's seems you do not handle it correctly because AddInUnload never returns when run at startup.

Do not assume that AddInMenu has been run before AddInUnload been called.

A work around would be to return ADDIN_PERSISTANT (0x1) in AddInLoad but i repeat that your addin do not fall into this category.

h.
Posted on 2003-11-03 13:15:34 by hitchhikr
Thanks for the reply. :)

I must have forgotten to return ADDIN_PERSISTANT... :P will be fixed.

The problem is I wanted to have a modeless dialog box. It is not possible to have one if the message queue does not support it, that's why I create a second thread and try to make the addin persistent.

Anyway, when I implement the tooltip feature I will need the addin to be persistant anyway, so this is a good time to implement that. ;)
Posted on 2003-11-03 13:46:57 by QvasiModo
Fixed the resizing code (it was really dumb... I got mixed up because I wasn't hosting the dialog inside the docking window before). Anyway it's still failing, but it must be one more of my stupid mistakes. Since I'm only giving to this project some 10 minutes or so every time, my coding tends to be really sloppy. I'll finish debugging the docking window support once I get myself the time to work on this for a good hour or two.
Meanwhile, here's version 2.0.2.1 (without docking windows support yet). I've tested it and it seems to work fine.

EDIT: Attachment removed. Latest version at the beginning of this thread.
Posted on 2003-11-04 16:09:00 by QvasiModo
This version is identical to the one above, but it works with docking windows (yes, I got them to work! :grin: ).
However... it seems to fail to save the window position properly... :(
I'll ask akyprian about it.

EDIT: Deleted the attachment since it was a buggy version.
Posted on 2003-11-05 17:31:53 by QvasiModo
Finally fixed. :grin:
Thanks akyprian!

EDIT: Attachment removed. Latest version at the beginning of this thread.
Posted on 2003-11-07 14:03:31 by QvasiModo
...approved :grin:

Nice addin !!!! Tx QvasiModo :alright:


Regards,
Posted on 2003-11-07 14:42:04 by PhoBos
Hi,

Very nice. You need to use WS_CLIPCHILDREN for your dialog to reduce flicker.(I do use it in my sample)

Cheers,

akyprian
Posted on 2003-11-07 15:35:26 by akyprian
Sure. Attachment updated. :)
Posted on 2003-11-08 07:54:05 by QvasiModo
Lovely! :alright:

Thanks,

akyprian
Posted on 2003-11-08 08:14:41 by akyprian
New version available (2.0.1.5). :)
Just a little cosmetic fix under WinAsm - now the addin will add it's menu item in the "View" menu, and will show a check mark if it's window is visible.
Posted on 2004-03-16 13:24:30 by QvasiModo
Thanks,

uploaded to my site,

akyprian
Posted on 2004-03-17 08:14:01 by akyprian