Source file: /~heha/messtech/sensokom.zip/source/TOOLSTAT.C

#ifdef _WIN32
# ifdef __BORLANDC__
#  pragma option -a4		// Word-Ausrichtung bei ACCEL
# else
#  pragma pack(4)		// Visual C
# endif
#else
# ifdef __BORLANDC__
#  pragma option -a-		// Byte-Ausrichtung bei ACCEL
# endif
#endif

#include <windows.h>
#include <windowsx.h>				// Message-Cracker
#ifndef GET_WM_COMMAND_CMD
# define GET_WM_COMMAND_CMD(wp,lp) HIWORD(lp)	//fehlt bei BC31 windowsx.h
#endif
#include "toolstat.h"
#include <commctrl.h>		// in dieser Reihenfolge!
#ifndef _WIN32
# undef TB_BUTTONCOUNT		// falsch definiert in commctrl.h: WM_USER+25
# define TB_BUTTONCOUNT	(WM_USER+24)
# undef TB_COMMANDTOINDEX	// falsch definiert in commctrl.h: WM_USER+26
# define TB_COMMANDTOINDEX (WM_USER+25)
# undef TB_SAVERESTORE		// falsch definiert in commctrl.h: WM_USER+28
# define TB_SAVERESTORE	(WM_USER+26)
# undef TB_CUSTOMIZE		// falsch definiert in commctrl.h: WM_USER+29
# define TB_CUSTOMIZE	(WM_USER+27)
#endif

HINSTANCE gHInstance;	/* globales HInstance */
LPCTSTR	StdProfile;	/* INI-Datei */
LPCTSTR HelpFileName;	/* Hilfe-Datei (für Kontexthilfe bei Werkzeugleiste)*/
HINSTANCE  hCommCtrl;	/* Handle der dynamisch geladenen DLL*/
HWND	MainWnd;	/* Handle des Hauptfensters*/
HMENU	MainMenu;	/* Handle des Hauptmenüs, wird zu oft gebraucht */
HACCEL	AccTable;	/* für Anzeige in ToolTips */
HWND	Toolbar;	/* Handle für Windows-Werkzeugleiste */
HWND	Status;		/* Handle für Windows-Statuszeile */

HLOCAL	ButtonDescript;	/* Kurzbeschreibungen zur Konfiguration der
			 Werkzeugleiste */
HGLOBAL	ButtonInfo;	/* Ressourcen-Objekt mit nachfolgenden Daten */
HLOCAL  MenuBitmaps;	/* Bitmap-Symbole für Menü */

#ifndef _WIN32
typedef VOID (WINAPI*tInitCommonControls)(VOID);
typedef HWND (WINAPI*tCreateStatusWindow)(LONG dwStyle, LPCTSTR lpszText,
  HWND hwndParent, UINT wID);
typedef HWND (WINAPI*tCreateToolbar)(HWND hParent, LONG dwStyle, UINT wID,
  int nBitmaps, HINSTANCE hBMInst, UINT wBMID, LPTBBUTTON lpButtons,
  int iNumButtons);
#endif

void LoadButtonInfo(void) {
 ButtonInfo=FindResource(gHInstance,MAKEINTRESOURCE(98),RT_RCDATA);
 if (ButtonInfo) ButtonInfo=LoadResource(gHInstance,ButtonInfo);
}

void SetMenuBitmaps(void) {
 LPRC_ButtonInfo rp;
 int j,k;
 HBITMAP bar,obar,bm,obm,near*mbp;
 HDC dc,dc_bar,dc_bm;
 DWORD p;

 if (!Toolbar) {	// tja!!
  LoadButtonInfo();
  if (!ButtonInfo) return;
 }
 rp=(LPRC_ButtonInfo)LockResource(ButtonInfo);
 p=GetMenuCheckMarkDimensions();
 dc=GetDC(MainWnd);
 dc_bar=CreateCompatibleDC(dc);
 dc_bm=CreateCompatibleDC(dc);
 bar=LoadBitmap(gHInstance,MAKEINTRESOURCE(98));
 obar=SelectObject(dc_bar,bar);
 MenuBitmaps=LocalAlloc(LMEM_MOVEABLE|LMEM_ZEROINIT,256*sizeof(HBITMAP));
 mbp=LocalLock(MenuBitmaps); j=0;
 for (k=0;rp->id;rp++,k+=16) {
  if (STY(rp->stasty)&TBSTYLE_CHECK) continue;	// CHECKbar: ohne Bitmap!
  bm=CreateCompatibleBitmap(dc,LOWORD(p),HIWORD(p));
  obm=SelectObject(dc_bm,bm);
  StretchBlt(dc_bm,0,0,LOWORD(p),HIWORD(p),dc_bar,k,0,16,15,SRCCOPY);
//  BitBlt(dc_bm,0,0,LOWORD(p),HIWORD(p),dc_bar,k+(16-LOWORD(p))/2,(15-HIWORD(p))/2,SRCCOPY);
  SelectObject(dc_bm,obm);		// Bitmap herauslösen
  SetMenuItemBitmaps(MainMenu,rp->id,0,bm,bm);
  *mbp++=bm; j++;
 }
 LocalUnlock(MenuBitmaps);
 LocalReAlloc(MenuBitmaps,j*sizeof(HBITMAP),0);
 ReleaseDC(MainWnd,dc);
 DeleteDC(dc_bm);
 SelectObject(dc_bar,obar);
 DeleteObject(bar);
 DeleteDC(dc_bar);
 UnlockResource(ButtonInfo);
 if (!Toolbar) FreeResource(ButtonInfo);
}

void DeleteMenuBitmaps(void) {
 int k=LocalSize(MenuBitmaps)/sizeof(HBITMAP);
 HBITMAP near*mbp=LocalLock(MenuBitmaps);
 for (;k;k--) {
  if (*mbp) DeleteObject(*mbp);
  mbp++;
 }
 LocalUnlock(MenuBitmaps);
 MenuBitmaps=LocalFree(MenuBitmaps);
}

static void MakeButtons(void) {
/*Erzeugt neue Werkzeugleiste oder setzt die vorher geleerte auf Startvorgaben*/
 PTBBUTTON b,bb;
 int i,k;
 LPRC_ButtonInfo rp;

 rp=(LPRC_ButtonInfo)LockResource(ButtonInfo);
/*Durchzählen der notwendigen TBButtons*/
 for (k=0;rp->id;rp++) {
  if (STY(rp->stasty)&TBSTYLE_SEP) k++;
  if (!(STA(rp->stasty)&TBSTATE_HIDDEN)) k++;
 }
 UnlockResource(ButtonInfo);
 i=k*sizeof(TBBUTTON);
/*Anlegen des TBButton-Arrays (eigentlich sinnlos, wenn's was zu laden gibt)*/
 b=(PTBBUTTON)LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT,i);
 rp=(LPRC_ButtonInfo)LockResource(ButtonInfo);
 for (bb=b,i=0;rp->id;rp++,i++) {
  if (STY(rp->stasty)&TBSTYLE_SEP) {
   bb->fsStyle=TBSTYLE_SEP;  /*heißt hier: Leerraum davor!*/
   bb++;
  }
  if (!(STA(rp->stasty)&TBSTATE_HIDDEN)) {
   bb->iBitmap=i;
   bb->idCommand=rp->id;
   *(WORD*)(&bb->fsState)=(WORD)(rp->stasty&~0xF108);
   bb->iString=i;
   bb++;
  }
 }
 UnlockResource(ButtonInfo);
/*i entspricht jetzt der Anzahl der Bilder! Erzeugen der Toolbar*/
 if (Toolbar) SendMessage(Toolbar,TB_ADDBUTTONS,k,(LPARAM)(LPTBBUTTON)b);
 else Toolbar=
#ifdef _WIN32
   CreateToolbarEx
#else
   ((tCreateToolbar)GetProcAddress(hCommCtrl,MAKEINTRESOURCE(7)))
#endif
   (MainWnd,WS_CHILD|WS_VISIBLE|WS_BORDER|
    CCS_ADJUSTABLE|TBSTYLE_TOOLTIPS|TBSTYLE_WRAPABLE,
   98,i,gHInstance,98,(LPTBBUTTON)b,k
#ifdef _WIN32
   ,16,15,16,15,sizeof(TBBUTTON)
#endif
   );
 LocalFree((HANDLE)b);
}

LPCTSTR GetFileNamePtr(LPCTSTR s) {
 LPCTSTR r;
 TCHAR c;
 for (r=s;;) {
  c=*s; s=AnsiNext(s);
  switch (c) {
   case ':':
   case '\\':
   case '/': r=s; break;
   case 0: return r;
  }
 }
}

LPCTSTR lstrchr(LPCTSTR s, TCHAR c) {
/* MBCS-sichere Zeichen- oder LeadByte-Suche */
 for(;;) {
  if (*s==c) return s;
  if (!*s) return NULL;
  s=AnsiNext(s);
 }
}

WORD Swap(WORD w) {
 return (w>>8)|(w<<8);
}

static void SaveRestore(BOOL save) {
/*Win9x speichert unter:
 HKCU\Software\Microsoft\Windows\CurrentVersion\ToolbarState\<section>*/
#ifdef _WIN32
 TBSAVEPARAMS sp;
 TCHAR s[MAX_PATH];
 GetModuleFileName(gHInstance,s,elemof(s));
 sp.hkr=HKEY_CURRENT_USER;
 sp.pszSubKey=T("Software\\Microsoft\\Windows\\CurrentVersion\\ToolbarState");
 sp.pszValueName=GetFileNamePtr(s);
 SendMessage(Toolbar,TB_SAVERESTORE,(WPARAM)save,(LPARAM)&sp);
#else
 LPCTSTR vsrec[2];
 TCHAR s[MAX_PATH];

 GetModuleFileName(gHInstance,s,elemof(s));
 vsrec[0]=GetFileNamePtr(s);
 vsrec[1]=StdProfile;
 if (StdProfile && Swap(LOWORD(GetVersion()))<3*256+95)  {
   /*falls in einer privaten .INI, dann einen besseren Sektionsnamen geben*/
  GetClassName(Toolbar,s,sizeof(s));   /*sollte "ToolbarWindow" liefern*/
  vsrec[0]=s;
 }
 SendMessage(Toolbar,TB_SAVERESTORE,(WPARAM)save,(LPARAM)(LPSTR)vsrec);
#endif
}

void ToggleToolbar(UINT MenuID) {
 int i;
 RECT R;
// CalcClientRect(&R);	// vorher
 if (!Toolbar) {
  if ((UINT)hCommCtrl>32) {
   ButtonDescript=LocalAlloc(LMEM_FIXED,512);
   i=LoadString(gHInstance,98,(NPSTR)ButtonDescript,256)+1;
   i+=LoadString(gHInstance,99,(NPSTR)ButtonDescript+i,256)+1;
   ButtonDescript=LocalReAlloc(ButtonDescript,i,LMEM_MOVEABLE);
   LoadButtonInfo();
   if (ButtonInfo) MakeButtons();
  }
  if (Toolbar) SaveRestore(FALSE);	/*Konfiguration laden*/
  else if (MenuID)            /*Noch Null: Da ging etwas schief!*/
    EnableMenuItem(MainMenu,MenuID,MF_GRAYED);
 }else{
  DestroyWindow(Toolbar);
  FreeResource(ButtonInfo);
  LocalFree(ButtonDescript);
  Toolbar=0;
 }
 if (MenuID) CheckMenuItem(MainMenu,MenuID,
   Toolbar?MF_CHECKED:MF_UNCHECKED);
// i=R.top;
 CalcClientRect(&R);
// if (!(GetClassLong(MainWnd,GCL_STYLE)&CS_VREDRAW)) {
//  UpdateWindow(MainWnd);
//  ScrollWindow(MainWnd,0,R.top-i,&R,NULL);
// }
 InvalidateRect(MainWnd,&R,TRUE);
}

void ToggleStatus(UINT MenuID) {
 RECT R;
 if (!Status) {
  if ((UINT)hCommCtrl>32)
  Status=
#ifdef _WIN32
    CreateStatusWindow
#else
    ((tCreateStatusWindow)GetProcAddress(hCommCtrl,MAKEINTRESOURCE(6)))
#endif
    (WS_VISIBLE|WS_CHILD|WS_BORDER,NULL,MainWnd,99);
  if (!Status && MenuID)	/*Misserfolg*/
    EnableMenuItem(MainMenu,MenuID,MF_GRAYED);
 }else{
  DestroyWindow(Status);
  Status=0;
 }
 if (MenuID)
   CheckMenuItem(MainMenu,MenuID,Status?MF_CHECKED:MF_UNCHECKED);
#ifdef _WIN32
 if (GetClassLong(MainWnd,GCL_STYLE)&CS_VREDRAW) {
#else
 if (GetClassWord(MainWnd,GCW_STYLE)&CS_VREDRAW) {
#endif
  CalcClientRect(&R);
  InvalidateRect(MainWnd,&R,TRUE);
 }
}

void WMMenuSelect(UINT id, UINT flags) {
 TCHAR s[128];
 if (!Status) return;
 if (flags==0xFFFF) {
  SendMessage(Status,SB_SIMPLE,FALSE,0);
  return;
 }
 if (flags&MF_POPUP) {
  int sub=0;				/* Ebenen-Zähler */
  HMENU submenu;
  for(;;){
   sub++;				/* Eine Ebene tiefer */
   submenu=(HMENU)id;			/* ist ein Popup-Menü-Handle */
   id=(UINT)GetSubMenu(submenu,0);	/* Vielleicht noch ein Popup-Menü? */
   if (!id) {				/* nein, dann raus! */
    id=GetMenuItemID(submenu,0)-sub;	/* endgültige ID */
    break;
   }
  }
 }
 if (!LoadString(gHInstance,id,s,sizeof(s))
 && flags&MF_SYSMENU) {
  id&=0x8FF0;
  if (flags&MF_POPUP) id=0x8FF0;
  LoadString(hCommCtrl,id&0x8FF0,s,sizeof(s));     /*da sind sie!*/
 }
 SendMessage(Status,SB_SIMPLE,TRUE,0);
 SendMessage(Status,SB_SETTEXT,255|SBT_NOBORDERS,(LPARAM)(LPSTR)s);
}

#ifndef _WIN32
static LPRC_ButtonInfo FindButton(UINT iButton) {
/*sperrt ButtonInfo und setzt Zeiger auf Knopf mit gleicher ID*/
 LPRC_ButtonInfo rp;
 TBBUTTON b;

 SendMessage(Toolbar,TB_GETBUTTON,iButton,(LPARAM)(LPTBBUTTON)&b);
 for (rp=(LPRC_ButtonInfo)LockResource(ButtonInfo);rp->id;rp++) {
  if (rp->id==b.idCommand) break;
 }
 return rp;
}
#endif

void Accel2Text(LPACCEL accel, LPTSTR s) {
 int i;
 for (i=0; i<3; i++) {
  if (accel->fVirt&(FSHIFT<<i)) {
   TCHAR s2[16];
   GetKeyNameText(MAKELONG(0,MapVirtualKey(VK_SHIFT+i,0)),
     s2,elemof(s2));
   s+=wsprintf(s,T("%s+"),(LPTSTR)s2);
  }
 }
 if (accel->fVirt&FVIRTKEY) {
  GetKeyNameText(MAKELONG(0,MapVirtualKey(accel->key,0)),
    s,32);
 }else{
  WORD k=accel->key;
  if (k<32) {
   *s++='^'; k+=64;	/*zur Kenntlichmachung WM_CHAR*/
  }
  *s++=(TCHAR)k;
  *s=0;
 }
}

#ifdef _WIN32
// unter Win32 kommt man nicht so einfach an die Tabelle heran!
static HLOCAL AccMem;
LPACCEL LockAccel(HACCEL a) {
 int i=CopyAcceleratorTable(a,NULL,0);
 AccMem=LocalAlloc(LMEM_FIXED,i*sizeof(ACCEL)+1);
 CopyAcceleratorTable(a,AccMem,i);
 ((LPBYTE)AccMem)[i*sizeof(ACCEL)]=0x80;	// Terminator
 return AccMem;
}
# define UnlockAccel(a) LocalFree(AccMem)
#else
# define LockAccel(a) (LPACCEL)LockResource(a)
# define UnlockAccel(a) UnlockResource(a)
#endif

void AppendAccel(LPTSTR s, UINT id) {
 LPACCEL acc;
 TCHAR s2[32];

 for (acc=LockAccel(AccTable);!(acc->fVirt&0x80);acc++) {
  if ((UINT)acc->cmd==id) {
   Accel2Text(acc,s2);
   wsprintf(s+lstrlen(s),T(" (%s)"),(LPTSTR)s2);
   break;		/*nicht mehrere! (unübersichtlich)*/
  }
 }
 UnlockAccel(AccTable);
}

void SetMenuAccels(HMENU m, HACCEL a, TCHAR delim) {
 LPACCEL acc;
 UINT ms;
 int cc;
 TCHAR s[64];
 TCHAR s2[32];

 for (acc=LockAccel(a);!(acc->fVirt&0x80);acc++) {
  ms=GetMenuState(m,acc->cmd,0);
  if (!(ms&(MF_BITMAP|MF_OWNERDRAW))) {
   cc=GetMenuString(m,acc->cmd,s,elemof(s),MF_BYCOMMAND);
   if (!lstrchr(s,delim))  {	/*nicht mehrfach*/
    Accel2Text(acc,s2);
    wsprintf(s+cc,T("%c%s"),delim,(LPTSTR)s2);
    ModifyMenu(m,acc->cmd,ms,acc->cmd,s);
   }
  }
 }
 UnlockAccel(a);
}

#ifndef _WIN32
static HANDLE hAdjust;      /*temporär für das Einrichten der Toolbar*/
#endif

LRESULT HandleToolStat(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
//  lPar: LongRec absolute lParam;
//  ttt: PToolTipText absolute lParam;
 LPRC_ButtonInfo rp;
 LPSTR sp;

 switch (Msg) {
  case WM_NCCREATE: {
#ifdef _WIN32			// bei Win32 nur für Systemmenü-Strings
   hCommCtrl=LoadLibrary("comctl32.dll");
   InitCommonControls();
#else				// bei Win16 darf die DLL auch fehlen
   UINT osem=SetErrorMode(SEM_NOOPENFILEERRORBOX);
   hCommCtrl=LoadLibrary("COMMCTRL.DLL");
   SetErrorMode(osem);
   if ((UINT)hCommCtrl>32)
     ((tInitCommonControls)GetProcAddress(hCommCtrl,MAKEINTRESOURCE(17)))();
#endif
  }break;
  case WM_CREATE: {
   MainWnd=Wnd;
   MainMenu=((LPCREATESTRUCT)lParam)->hMenu;
   if (MainMenu) SetMenuAccels(MainMenu,AccTable,9);
  }break;

  case WM_SIZE: {
   if (Toolbar) SendMessage(Toolbar,Msg,0,0);
   if (Status)  SendMessage(Status,Msg,0,0);
  }break;

#ifndef _WIN32
  case WM_COMMAND: switch (LOWORD(wParam)) {
   case 98: switch (GET_WM_COMMAND_CMD(wParam,lParam)) {
    case TBN_BEGINDRAG: SendMessage(Wnd,WM_MENUSELECT,(WPARAM)lParam,0); break;
    case TBN_ENDDRAG: SendMessage(Wnd,WM_MENUSELECT,0,0x0000FFFF); break;
    case TBN_BEGINADJUST: {
     int i,j;
	/*Länge der längsten Beschreibung bestimmen*/
     rp=(LPRC_ButtonInfo)LockResource(ButtonInfo);
     sp=LocalLock(ButtonDescript);
     i=0;
     for (i=0;rp->id;rp++) {
      j=lstrlen(sp);
      i=max(i,j);
      sp+=j+1;
     }
     LocalUnlock(ButtonDescript);
     UnlockResource(ButtonInfo);
	/*Speicherblock anfordern und für TBN_AdjustInfo bereithalten*/
     hAdjust=GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
       sizeof(ADJUSTINFO)+i);
    }break;

    case TBN_ADJUSTINFO: {
	/*Solange AdjustInfos liefern, bis lPar.lo zu groß wird*/
     rp=(LPRC_ButtonInfo)LockResource(ButtonInfo);
     rp+=LOWORD(lParam);         /*lPar.lo = Button-Index*/
     if (rp->id) {
      LPADJUSTINFO ai=(LPADJUSTINFO)GlobalLock(hAdjust);
      ai->tbButton.iBitmap=LOWORD(lParam);
      ai->tbButton.idCommand=rp->id;
      *(LPWORD)&ai->tbButton.fsState=rp->stasty&~0xF108;
      ai->tbButton.idsHelp=LOWORD(lParam);
      sp=LocalLock(ButtonDescript);
      for (;LOWORD(lParam);LOWORD(lParam)--) {  /*richtigen String suchen*/
       sp+=lstrlen(sp)+1;
      }
      lstrcpy(ai->szDescription,sp);
      LocalUnlock(ButtonDescript);
      GlobalUnlock(hAdjust);
      return (LRESULT)hAdjust;
     }
     UnlockResource(ButtonInfo);
    }break;

    case TBN_ENDADJUST: GlobalFree(hAdjust); break;

    case TBN_RESET: {
     while (SendMessage(Toolbar,TB_DELETEBUTTON,0,0));	/*alle löschen*/
     MakeButtons();             /*und neu setzen*/
     SaveRestore(TRUE);		/*und speichern*/
    }break;

    case TBN_QUERYINSERT: return TRUE;       /*stets links einfügen lassen*/

    case TBN_QUERYDELETE: {
     rp=FindButton(LOWORD(lParam));
     if (!(STY(rp->stasty)&0x10)) {
      UnlockResource(ButtonInfo);
      return TRUE;      /*Aktion erlauben*/
     }
     UnlockResource(ButtonInfo);
    }break;

    case TBN_TOOLBARCHANGE: SaveRestore(TRUE); break;     /*abspeichern*/

    case TBN_CUSTHELP: WinHelp(MainWnd,HelpFileName,HELP_CONTEXT,98);
   }
  }break;
#endif

  case WM_NOTIFY: {			/*ab Win95*/
#define ttt ((LPTOOLTIPTEXT)lParam)
#ifndef _WIN32
   if (IsBadWritePtr(ttt,sizeof(TOOLTIPTEXT))) break;
#endif
   switch (ttt->hdr.code) {
    case TTN_NEEDTEXT: {
		/*wParam = Button-Nummer ermitteln*/
     for (rp=LockResource(ButtonInfo),wParam=0;rp->id;rp++,wParam++) {
      if ((UINT)rp->id==ttt->hdr.idFrom) break;
     }
     UnlockResource(ButtonInfo);
     sp=LocalLock(ButtonDescript);
     while (wParam) {	/*richtigen String suchen*/
      sp+=lstrlen(sp)+1;
      wParam--;
     }
     lstrcpyn(ttt->szText,sp,sizeof(ttt->szText));
     LocalUnlock(ButtonDescript);
     AppendAccel(ttt->szText,ttt->hdr.idFrom);
    }break;
#ifdef _WIN32
    case TBN_QUERYINSERT:
    case TBN_QUERYDELETE: {
    }return TRUE;
    case TBN_BEGINDRAG: WMMenuSelect(
      ((LPTBNOTIFY)lParam)->iItem,0); break;
    case TBN_ENDDRAG: WMMenuSelect(0,0xFFFF); break;
    case TBN_CUSTHELP: WinHelp(MainWnd,HelpFileName,HELP_CONTEXT,98); break;
#endif
   }
#undef ttt
  }break;

  case WM_MENUSELECT: WMMenuSelect(
#ifdef _WIN32		/* Fallstrick Win32 */
    HIWORD(wParam)&MF_POPUP
      ?(UINT)GetSubMenu((HMENU)lParam,LOWORD(wParam))
      :LOWORD(wParam),
    HIWORD(wParam)
#else
    wParam,LOWORD(lParam)
#endif
    ); break;

  case WM_DESTROY: {			/*Fenster ggf. aufräumen*/
   if (Toolbar) ToggleToolbar(0);	/*Menü-ID sowieso unwichtig*/
   if (Status ) ToggleStatus(0);
  }break;
  case WM_NCDESTROY: {
   if ((UINT)hCommCtrl>32) FreeLibrary(hCommCtrl);
  }break;
 }
 return 0;
}

void CalcClientRect(LPRECT R) {
 RECT R2;
 GetClientRect(MainWnd,R);
 if (Toolbar) {
  GetWindowRect(Toolbar,&R2);
  ScreenToClient(MainWnd,(LPPOINT)&R2.right);
  R->top=R2.bottom;
 }
 if (Status) {
  GetWindowRect(Status,&R2);
  ScreenToClient(MainWnd,(LPPOINT)&R2.left);
  R->bottom=R2.top;
 }
}


Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded