_SysDebug("DoRun pressed");
char *cmd = AxWin3_Widget_GetText(gRunInput);
_SysDebug("Command string '%s'", cmd);
+
+ // TODO: Parse the command string into components
+ // TODO: Call _SysSpawn
+
AxWin3_ShowWindow(gRunDialog, 0);
return 0;
}
#define AXWIN_VERSION 0x300
+static inline int MIN(int a, int b) { return (a < b) ? a : b; }
+static inline int MAX(int a, int b) { return (a > b) ? a : b; }
+
// === GLOBALS ===
extern int giTerminalFD;
extern const char *gsTerminalDevice;
#define WINFLAG_MAXIMIZED 0x00000004
//! Window is contained within the parent
#define WINFLAG_RELATIVE 0x00000008
+//! Window needs to be reblitted (child moved or contents changed)
+#define WINFLAG_NEEDREBLIT 0x00000020
//! Window contents are valid
#define WINFLAG_CLEAN 0x00000040
//! All child windows are un-changed
extern tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int Flags, const char *Renderer);
extern void WM_DestroyWindow(tWindow *Window);
extern tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID);
-extern void WM_Invalidate(tWindow *Window);
+extern void WM_Invalidate(tWindow *Window, int bClearClean);
extern void WM_SetWindowTitle(tWindow *Window, const char *Title);
extern void WM_FocusWindow(tWindow *Destination);
extern void WM_RaiseWindow(tWindow *Window);
int IPC_Type_IPCPipe_Compare(const void *Ident1, const void *Ident2);
void IPC_Type_IPCPipe_Send(const void *Ident, size_t Length, const void *Data);
tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident);
+void IPC_int_DropClient(tIPC_Client *Client);
void IPC_Handle(tIPC_Client *Client, size_t MsgLen, tAxWin_IPCMessage *Msg);
// === GLOBALS ===
if( giIPCPipeHandle != -1 && FD_ISSET(giIPCPipeHandle, set) )
{
int newfd = _SysOpenChild(giIPCPipeHandle, "newclient", OPENFLAG_READ|OPENFLAG_WRITE);
- _SysDebug("newfd = %i");
+ _SysDebug("newfd = %i", newfd);
IPC_int_GetClient(&gIPC_Type_IPCPipe, &newfd);
}
char staticBuf[STATICBUF_SIZE];
size_t len;
len = _SysRead(fd, staticBuf, sizeof(staticBuf));
+ if( len == (size_t)-1 ) {
+ // TODO: Check errno for EINTR
+ IPC_int_DropClient(gIPC_Clients[i]);
+ break;
+ }
IPC_Handle( gIPC_Clients[i], len, (void*)staticBuf );
}
}
return a->IPCType->CompareIdent(a->Ident, b->Ident);
}
+int IPC_int_BSearchClients(const tIPC_Client *TargetClient, int *Pos)
+{
+ int div;
+ int cmp = -1;
+ int pos = 0;
+
+ div = giIPC_ClientCount;
+ pos = div/2;
+ while(div > 0)
+ {
+ div /= 2;
+ cmp = _CompareClientPtrs(&TargetClient, &gIPC_Clients[pos]);
+// _SysDebug("Checking against %i gives %i", pos, cmp);
+ if(cmp == 0) break;
+ if(cmp < 0)
+ pos -= div;
+ else
+ pos += div;
+ }
+
+ // - Return if found
+ if(cmp == 0) {
+ *Pos = pos;
+ return 1;
+ }
+
+ // Adjust pos to be the index where the new client will be placed
+ if(cmp > 0) pos ++;
+ *Pos = pos;
+ return 0;
+}
+
tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident)
{
int pos = 0; // Position where the new client will be inserted
if(giIPC_ClientCount > 0)
{
tIPC_Client target;
- int div;
- int cmp = -1;
-
target.IPCType = IPCType;
target.Ident = Ident;
- ret = ⌖ // Abuse ret to get a pointer
-
- div = giIPC_ClientCount;
- pos = div/2;
- while(div > 0)
- {
- div /= 2;
- cmp = _CompareClientPtrs(&ret, &gIPC_Clients[pos]);
-// _SysDebug("Checking against %i gives %i", pos, cmp);
- if(cmp == 0) break;
- if(cmp < 0)
- pos -= div;
- else
- pos += div;
- }
-
- // - Return if found
- if(cmp == 0)
+ if( IPC_int_BSearchClients(&target, &pos) )
return gIPC_Clients[pos];
-
- // Adjust pos to be the index where the new client will be placed
- if(cmp > 0) pos ++;
}
return ret;
}
+void IPC_int_DropClient(tIPC_Client *Client)
+{
+ // Remove from client list
+ int pos;
+ if( !IPC_int_BSearchClients(Client, &pos) ) {
+ _SysDebug("IPC_int_DropClient: Can't find client %p", Client);
+ return ;
+ }
+
+ giIPC_ClientCount --;
+ memmove(&gIPC_Clients[pos], &gIPC_Clients[pos+1], (giIPC_ClientCount-pos)*sizeof(tIPC_Client*));
+
+ // Terminate client's windows
+ // - If there were active windows, show an error?
+ int nWindowsDestroyed = 0;
+ for(int i = 0; i < Client->nWindows; i ++)
+ {
+ if( Client->Windows[i] )
+ {
+ _SysDebug("Window %p:%i %p still exists", Client, i, Client->Windows[i]);
+ WM_DestroyWindow(Client->Windows[i]);
+ nWindowsDestroyed ++;
+ }
+ }
+ if( nWindowsDestroyed )
+ {
+ _SysDebug("TODO: Show notice that application exited without destroying windows");
+ }
+
+ // Free client structure
+ free(Client);
+ _SysDebug("Dropped client %p", Client);
+}
+
tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t WindowID)
{
if( WindowID == -1 )
return 0;
WM_DestroyWindow(win);
+ IPC_int_SetWindow(Client, Msg->Window, NULL);
return 0;
}
{
tWindow *win = IPC_int_GetWindow(Client, Msg->Window);
if( !win ) {
- _SysDebug("WARNING: NULL window in message %i", Msg->ID);
+ _SysDebug("WARNING: NULL window in message %i (%x)", Msg->ID, Msg->Window);
return ;
}
tWMRenderer *renderer = win->Renderer;
{
info->HilightedItem = new_hilight;
// TODO: Change sub-menu
- WM_Invalidate(Window);
+ WM_Invalidate(Window, 1);
}
return 0; }
struct sRichText_Line *Next;
struct sRichText_Line *Prev;
int Num;
+ char bIsClean;
// TODO: Pre-rendered cache?
short ByteLength;
short Space;
tColour DefaultFG;
tColour DefaultBG;
tFont *Font;
+ char bNeedsFullRedraw;
short LineHeight;
} tRichText_Window;
void Renderer_RichText_Redraw(tWindow *Window)
{
tRichText_Window *info = Window->RendererInfo;
- int i;
tRichText_Line *line = info->FirstVisLine;
if( !line ) {
while( line && line->Prev && line->Prev->Num > info->FirstVisRow )
line = line->Prev;
+ int i;
for( i = 0; i < info->DispLines && line; i ++ )
{
if( i >= info->nLines - info->FirstVisRow )
break;
- // TODO: Dirty rectangles?
+ // Empty line is noted by a discontinuity
+ if( line->Num > info->FirstVisRow + i ) {
+ // Clear line if window needs full redraw
+ if( info->bNeedsFullRedraw ) {
+ WM_Render_FillRect(Window,
+ 0, i*info->LineHeight,
+ Window->W, info->LineHeight,
+ info->DefaultBG
+ );
+ }
+ else {
+ // Hack to clear cursor on NULL lines
+ WM_Render_FillRect(Window,
+ 0, i*info->LineHeight,
+ 1, info->LineHeight,
+ info->DefaultBG
+ );
+ }
+ continue ;
+ }
+
+ if( info->bNeedsFullRedraw || !line->bIsClean )
+ {
+ WM_Render_FillRect(Window,
+ 0, i*info->LineHeight,
+ Window->W, info->LineHeight,
+ info->DefaultBG
+ );
+
+ // Formatted text out
+ Renderer_RichText_RenderText(Window, i, line->Data);
+ _SysDebug("RichText: %p - Render %i '%.*s'", Window,
+ line->Num, line->ByteLength, line->Data);
+ line->bIsClean = 1;
+ }
+
+ line = line->Next;
+ }
+ // Clear out lines i to info->DispLines-1
+ if( info->bNeedsFullRedraw )
+ {
+ _SysDebug("RichText: %p - Clear %i px lines with %06x starting at %i",
+ Window, (info->DispLines-i)*info->LineHeight, info->DefaultBG, i*info->LineHeight);
WM_Render_FillRect(Window,
0, i*info->LineHeight,
- Window->W, info->LineHeight,
+ Window->W, (info->DispLines-i)*info->LineHeight,
info->DefaultBG
);
- if( line->Num > info->FirstVisRow + i )
- continue ;
- // TODO: Horizontal scrolling?
- // TODO: Formatting
-
- // Formatted text out
- Renderer_RichText_RenderText(Window, i, line->Data);
- _SysDebug("RichText: %p - Render %i '%.*s'", Window,
- line->Num, line->ByteLength, line->Data);
-
- line = line->Next;
}
- // Clear out i -- info->DispLines
- _SysDebug("RichText: %p - Clear %i px lines with %06x starting at %i",
- Window, (info->DispLines-i)*info->LineHeight, info->DefaultBG, i*info->LineHeight);
- WM_Render_FillRect(Window,
- 0, i*info->LineHeight,
- Window->W, (info->DispLines-i)*info->LineHeight,
- info->DefaultBG
- );
+ info->bNeedsFullRedraw = 0;
- // HACK!
+ // HACK: Hardcoded text width of 8
info->DispCols = Window->W / 8;
- // TODO: Text cursor
+ // Text cursor
_SysDebug("Cursor at %i,%i", info->CursorCol, info->CursorRow);
_SysDebug(" Range [%i+%i],[%i+%i]", info->FirstVisRow, info->DispLines, info->FirstVisCol, info->DispCols);
if( info->CursorRow >= info->FirstVisRow && info->CursorRow < info->FirstVisRow + info->DispLines )
}
}
+tRichText_Line *Renderer_RichText_int_GetLine(tWindow *Window, int LineNum, tRichText_Line **Prev)
+{
+ tRichText_Window *info = Window->RendererInfo;
+ tRichText_Line *line = info->FirstLine;
+ tRichText_Line *prev = NULL;
+ while(line && line->Num < LineNum)
+ prev = line, line = line->Next;
+
+ if( Prev )
+ *Prev = prev;
+
+ if( !line || line->Num > LineNum )
+ return NULL;
+ return line;
+}
+
int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data)
{
tRichText_Window *info = Window->RendererInfo;
case _ATTR_DEFFG:
info->DefaultFG = msg->Value;
break;
- case _ATTR_CURSORPOS:
- info->CursorRow = msg->Value >> 12;
- info->CursorCol = msg->Value & 0xFFF;
- break;
+ case _ATTR_CURSORPOS: {
+ int newRow = msg->Value >> 12;
+ int newCol = msg->Value & 0xFFF;
+ // Force redraw of old and new row
+ tRichText_Line *line = Renderer_RichText_int_GetLine(Window, info->CursorRow, NULL);
+ if( line )
+ line->bIsClean = 0;
+ if( newRow != info->CursorRow ) {
+ line = Renderer_RichText_int_GetLine(Window, newRow, NULL);
+ if(line)
+ line->bIsClean = 0;
+ }
+ info->CursorRow = newRow;
+ info->CursorCol = newCol;
+ WM_Invalidate(Window, 1);
+ break; }
case _ATTR_SCROLL:
// TODO: Set scroll flag
break;
if( Len < sizeof(*msg) ) return -1;
if( msg->Line >= info->nLines ) return 1; // Bad count
- tRichText_Line *line = info->FirstLine;
tRichText_Line *prev = NULL;
- while(line && line->Num < msg->Line)
- prev = line, line = line->Next;
- if( !line || line->Num > msg->Line )
+ tRichText_Line *line = Renderer_RichText_int_GetLine(Window, msg->Line, &prev);
+ if( !line )
{
// New line!
// Round up to 32
int space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1);
tRichText_Line *new = malloc(sizeof(*line) + space);
// TODO: Bookkeeping on how much memory each window uses
- new->Next = line;
+ new->Next = (prev ? prev->Next : NULL);
new->Prev = prev;
new->Num = msg->Line;
new->Space = space;
}
line->ByteLength = Len - sizeof(*msg);
memcpy(line->Data, msg->LineData, Len - sizeof(*msg));
+ line->bIsClean = 0;
- WM_Invalidate( Window );
+// WM_Invalidate(Window, 1);
- return 0;
+ return 0;
}
int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
const struct sWndMsg_Resize *msg = Data;
if(Len < sizeof(*msg)) return -1;
info->DispLines = msg->H / info->LineHeight;
+ info->bNeedsFullRedraw = 1; // force full rerender
return 1; }
case WNDMSG_KEYDOWN:
case WNDMSG_KEYUP:
}
// TODO: Have a Widget_ function to do this instead
- WM_Invalidate(Element->Window);
+ WM_Invalidate(Element->Window, 1);
return 0;
}
_SysDebug("Video_Update - Sending FD %i %p 0x%x", giTerminalFD, gpScreenBuffer+ofs, size*4);
_SysWrite(giTerminalFD, gpScreenBuffer+ofs, size*4);
_SysDebug("Video_Update - Done");
- giVideo_FirstDirtyLine = 0;
+ giVideo_FirstDirtyLine = giScreenHeight;
giVideo_LastDirtyLine = 0;
}
if( W <= 0 || H <= 0 ) return;
- if( DstY < giVideo_FirstDirtyLine )
- giVideo_FirstDirtyLine = DstY;
- if( DstY + H > giVideo_LastDirtyLine )
- giVideo_LastDirtyLine = DstY + H;
+ giVideo_FirstDirtyLine = MIN(DstY, giVideo_FirstDirtyLine);
+ giVideo_LastDirtyLine = MAX(DstY+H, giVideo_LastDirtyLine);
buf = gpScreenBuffer + DstY*giScreenWidth + DstX;
if(drawW != giScreenWidth || W != giScreenWidth)
else
Window->Parent->LastChild = prev;
}
- WM_Invalidate(Window->Parent);
+ // - Full invalidate
+ WM_Invalidate(Window, 1);
// - Remove from inheritance tree?
if( Window->Renderer->DestroyWindow )
Window->Renderer->DestroyWindow(Window);
else
- _SysDebug("WARN: Renderer %s does not have a destroy function", Window->Renderer->Name);
+ _SysDebug("WARN: Renderer '%s' does not have a destroy function", Window->Renderer->Name);
// - Tell client to clean up
WM_SendMessage(NULL, Window, WNDMSG_DESTROY, 0, NULL);
_msg.Val = 1;
WM_SendMessage(NULL, Destination, WNDMSG_FOCUS, sizeof(_msg), &_msg);
}
-
- WM_Invalidate(gpWM_FocusedWindow);
- WM_Invalidate(Destination);
+
+ // TODO: Leave it up to the renderer to decide to invalidate
+ WM_Invalidate(gpWM_FocusedWindow, 1);
+ WM_Invalidate(Destination, 1);
gpWM_FocusedWindow = Destination;
}
if( !!(Window->Flags & WINFLAG_SHOW) == bShow )
return ;
+
+ // Window is being hidden, invalidate parents
+ if( !bShow )
+ WM_Invalidate(Window, 0);
// Message window
_msg.Val = !!bShow;
_SysDebug("Window %p hidden", Window);
}
- WM_Invalidate(Window);
+ // Window has been shown, invalidate everything
+ if( bShow )
+ WM_Invalidate(Window, 1);
}
void WM_DecorateWindow(tWindow *Window, int bDecorate)
Window->RenderBuffer = NULL;
}
- WM_Invalidate(Window);
+ WM_Invalidate(Window, 1);
}
void WM_SetRelative(tWindow *Window, int bRelativeToParent)
}
// TODO: Re-sanitise
+ if( Window->X == X && Window->Y == Y ) {
+ _SysDebug("WM_MoveWindow: Equal (%i,%i)", X, Y);
+ return 0;
+ }
+
+ if( Window->Parent )
+ Window->Parent->Flags |= WINFLAG_NEEDREBLIT;
+
_SysDebug("WM_MoveWindow: (%i,%i)", X, Y);
Window->X = X; Window->Y = Y;
// Mark up the tree that a child window has changed
- while( (Window = Window->Parent) )
- Window->Flags &= ~WINFLAG_CHILDCLEAN;
+ WM_Invalidate(Window, 0);
return 0;
}
if( Window->W == W && Window->H == H )
return 0;
+
+ // If the window size has decreased, force the parent to reblit
+ if( Window->Parent && (Window->W > W || Window->H > H) )
+ Window->Parent->Flags |= WINFLAG_NEEDREBLIT;
- _SysDebug("WM_ResizeWindow: %ix%i", W, H);
+ _SysDebug("WM_ResizeWindow: %p:%i %ix%i", Window->Client, Window->ID, W, H);
Window->W = W; Window->H = H;
if(Window->RenderBuffer) {
free(Window->RenderBuffer);
Window->RenderBuffer = NULL;
}
- WM_Invalidate(Window);
+ WM_Invalidate(Window, 1);
{
struct sWndMsg_Resize msg;
return 0;
}
-void WM_Invalidate(tWindow *Window)
+void WM_Invalidate(tWindow *Window, int bClearClean)
{
if(!Window) return ;
-// _SysDebug("Invalidating %p", Window);
- // Don't invalidate twice (speedup)
-// if( !(Window->Flags & WINFLAG_CLEAN) ) return;
-
+
+ // Don't bother invalidating if the window isn't shown
+ if( !(Window->Flags & WINFLAG_SHOW) )
+ return ;
+
// Mark for re-render
- Window->Flags &= ~WINFLAG_CLEAN;
+ if( bClearClean )
+ Window->Flags &= ~WINFLAG_CLEAN;
// Mark up the tree that a child window has changed
- while( (Window = Window->Parent) )
+ while( (Window = Window->Parent) && (Window->Flags & WINFLAG_SHOW) )
Window->Flags &= ~WINFLAG_CHILDCLEAN;
}
}
Window->Renderer->Redraw(Window);
- Window->Flags |= WINFLAG_CLEAN;
+ Window->Flags |= WINFLAG_CLEAN|WINFLAG_NEEDREBLIT;
}
// Process children
Decorator_Redraw(Window);
}
-void WM_int_BlitWindow(tWindow *Window)
+void WM_int_BlitWindow(tWindow *Window, int bForceReblit)
{
tWindow *child;
// _SysDebug("Blit %p (%p) to (%i,%i) %ix%i", Window, Window->RenderBuffer,
// Window->RealX, Window->RealY, Window->RealW, Window->RealH);
- Video_Blit(Window->RenderBuffer, Window->RealX, Window->RealY, Window->RealW, Window->RealH);
+ // TODO Don't blit unless:
+ // a) A parent has been reblitted (thus clobbering the existing content)
+ // b) A child has moved (exposing a previously hidden area)
+ if( bForceReblit || (Window->Flags & WINFLAG_NEEDREBLIT) )
+ {
+ Video_Blit(Window->RenderBuffer, Window->RealX, Window->RealY, Window->RealW, Window->RealH);
+ Window->Flags &= ~WINFLAG_NEEDREBLIT;
+ bForceReblit = 1;
+ }
if( Window == gpWM_FocusedWindow && Window->CursorW )
{
for( child = Window->FirstChild; child; child = child->NextSibling )
{
- WM_int_BlitWindow(child);
+ WM_int_BlitWindow(child, bForceReblit);
}
}
WM_int_UpdateWindow(gpWM_RootWindow);
// - Draw windows from back to front to the render buffer
- WM_int_BlitWindow(gpWM_RootWindow);
+ WM_int_BlitWindow(gpWM_RootWindow, 0);
Video_Update();
}
*/
enum eWM_WindowMessages
{
- WNDMSG_NULL,
+ WNDMSG_NULL, // 0
- WNDMSG_CREATE,
- WNDMSG_DESTROY,
- WNDMSG_CLOSE,
- WNDMSG_FOCUS, // Called on change
- WNDMSG_SHOW, // Called on change
+ WNDMSG_CREATE, // 1
+ WNDMSG_DESTROY, // 2
+ WNDMSG_CLOSE, // 3
+ WNDMSG_FOCUS, // 4 Called on change
+ WNDMSG_SHOW, // 5 Called on change
- WNDMSG_RESIZE,
+ WNDMSG_RESIZE, // 6
- WNDMSG_MOUSEMOVE,
- WNDMSG_MOUSEBTN,
- WNDMSG_KEYDOWN,
- WNDMSG_KEYFIRE,
- WNDMSG_KEYUP,
+ WNDMSG_MOUSEMOVE, // 7
+ WNDMSG_MOUSEBTN, // 8
+ WNDMSG_KEYDOWN, // 9
+ WNDMSG_KEYFIRE, // 10
+ WNDMSG_KEYUP, // 11
WNDMSG_HOTKEY,
{
tRichText_Window *info = AxWin3_int_GetDataPtr(Window);
struct sWndMsg_KeyAction *keyaction = Data;
- _SysDebug("MessageID = %i", MessageID);
switch(MessageID)
{
case WNDMSG_KEYFIRE:
if(Size < sizeof(*keyaction)) return -1;
info->KeyCallback(Window, 2, keyaction->KeySym, keyaction->UCS32);
return 1;
+ case WNDMSG_KEYDOWN:
+ if(Size < sizeof(*keyaction)) return -1;
+ info->KeyCallback(Window, 1, keyaction->KeySym, keyaction->UCS32);
+ return 1;
+ case WNDMSG_KEYUP:
+ if(Size < sizeof(*keyaction)) return -1;
+ info->KeyCallback(Window, 0, keyaction->KeySym, 0);
+ return 1;
}
return 0;
}
#include <widget_messages.h>
#include <string.h>
+//static const int ciBaseElementCount = 16;
+static const int ciStepElementCount = 16;
+
// === STRUCTURES ===
struct sAxWin3_Widget
{
}
if( newID == Info->nElements )
{
- const int size_step = 4;
- Info->nElements += 4;
+ Info->nElements += ciStepElementCount;
Info->Elements = realloc(Info->Elements, sizeof(*Info->Elements)*Info->nElements);
- newID = Info->nElements - 4;
- memset( &Info->Elements[newID+1], 0, (size_step-1)*sizeof(Info->Elements));
+ newID = Info->nElements - ciStepElementCount;
+ memset( &Info->Elements[newID+1], 0, (ciStepElementCount-1)*sizeof(Info->Elements));
_SysDebug("Widget: Expanded to %i and allocated %i", Info->nElements, newID);
}
else
switch(MessageID)
{
+// case WNDMSG_DESTROY: {
+// return 0; }
case MSG_WIDGET_FIRE: {
tWidgetMsg_Fire *msg = Data;
if(Size < sizeof(*msg)) return -1;
widget = AxWin3_Widget_int_GetElementByID(Window, msg->WidgetID);
if(widget->Fire) widget->Fire(widget);
+ return 1; }
+ case MSG_WIDGET_KEYPRESS: {
+ return 0; }
+ case MSG_WIDGET_MOUSEBTN: {
+ // TODO: Do something
return 1; }
default:
return 0;
return block->Windows[ServerID];
}
+void AxWin3_int_DelWindowByID(uint32_t ServerID)
+{
+ int orig_id = ServerID;
+ tWindowBlock *block = &gAxWin3_WindowList;
+ while(block && ServerID > WINDOWS_PER_ALLOC) {
+ block = block->Next;
+ ServerID -= WINDOWS_PER_ALLOC;
+ }
+ if( !block || !block->Windows[ServerID] )
+ _SysDebug("AxWin3_int_DelWindowByID - Id %i out of range", orig_id);
+ else
+ block->Windows[ServerID] = NULL;
+}
+
tWindow *AxWin3_int_AllocateWindowInfo(int DataBytes, int *WinID)
{
int idx, newWinID;
case WNDMSG_DESTROY:
_SysDebug("TODO: Check that WNDMSG_DESTROY was from us calling _DestroyWindow");
// TODO: Finalise cleanup of window, this will be the last message sent to this window
+ AxWin3_int_DelWindowByID(Win->ServerID);
return 1;
default:
return 0;