Source file: /~heha/ewa/Motor/cdesk.zip/drawtexthook.cpp

// MSVC6 without standard library but with MSVCRT.DLL

#include <windows.h>
#include <algorithm>	// std::swap()
#include <tchar.h>
#include "text.h"

#pragma comment(linker,"/NOD /RELEASE /SUBSYSTEM:WINDOWS,4.00 /OPT:NOWIN98 /LARGEADDRESSAWARE")
#pragma intrinsic(memcpy)
#define elemof(x) (sizeof(x)/sizeof(*(x)))

#pragma pack(push,1)
struct JumpInstr{
  typedef BYTE buf_t[5];	// byte buffer for saving and restoring
  BYTE opcode;			// 0xE9: same for x86 and x64
  LONG distance;		// distance between target and end-of-opcode, same for x86 and x64
  const void*end() const {return this+1;}	// end-of-opcode
  void save(buf_t buf) const {memcpy(buf,this,5);}
  void restore(const buf_t buf) {memcpy(this,buf,5);}
  void swap(buf_t buf) {std::swap(*this,*(JumpInstr*)buf);}
  void setjmp(const void*target) {opcode=0xE9; distance=LONG((BYTE*)target-(BYTE*)end());}
};
#pragma pack(pop)

static JumpInstr*dt;		// USER32.DLL::DrawTextW
static JumpInstr::buf_t dt_buf;

static JumpInstr*dtex;		// same for DrawTextExW
static JumpInstr::buf_t dtex_buf;

void _cdecl debug(const TCHAR*t,...) {
 va_list va;
 va_start(va,t);
 TCHAR s[256];
 _sntprintf(s,elemof(s),t,va);
 va_end(va);
 OutputDebugString(s);
}
#if 0
int WINAPI DrawTextX(HDC dc,const TCHAR*s,int slen,RECT*rc,UINT uFormat) {
  debug(TEXT("DrawText(%X,\"%s\",%d,{%d,%d,%d,%d},%X)\n"),dc,s,slen,rc?rc->left:0,rc?rc->top:0,rc?rc->right:0,rc?rc->bottom:0,uFormat);
  dt->swap(dt_buf);	// of-course, needs single-threading
  int i=DrawText(dc,const_cast<TCHAR*>(s),slen,rc,uFormat);
  dt->swap(dt_buf);
  return i;
}

int WINAPI DrawTextExX(HDC dc,const TCHAR*s,int slen,RECT*rc,UINT uFormat,DRAWTEXTPARAMS*dtp) {
  debug(TEXT("DrawTextEx(%X,\"%s\",%d,{%d,%d,%d,%d},%X,%X)\n"),dc,s,slen,rc?rc->left:0,rc?rc->top:0,rc?rc->right:0,rc?rc->bottom:0,uFormat,dtp);
  dtex->swap(dtex_buf);	// of-course, needs single-threading
  int i=DrawTextEx(dc,const_cast<TCHAR*>(s),slen,rc,uFormat,dtp);
  dtex->swap(dtex_buf);
  return i;
}
#endif
void WinMainCRTStartup() {
  dt=(JumpInstr*)DrawTextW;	// USER32.DLL::DrawTextW
  dtex=(JumpInstr*)DrawTextExW;	// same for DrawTextExW
  DWORD oldprot[2];
  VirtualProtect(dt,sizeof*dt,PAGE_EXECUTE_WRITECOPY,oldprot);
  dt->save(dt_buf);
  dt->setjmp(DrawTextXW);

  VirtualProtect(dtex,sizeof*dtex,PAGE_EXECUTE_WRITECOPY,oldprot+1);
  dtex->save(dtex_buf);
  dtex->setjmp(DrawTextExXW);

  HWND w=CreateWindowEx(0,TEXT("Static"),TEXT("Test&123"),WS_OVERLAPPEDWINDOW|WS_VISIBLE,
  CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
  0,0,0,0);
  ShowWindow(w,SW_SHOWDEFAULT);
  UpdateWindow(w);
  MessageBox(w,TEXT("Hier ist\n&mehrzeiliger Text"),0,MB_OK|MB_ICONEXCLAMATION);
  dtex->restore(dtex_buf);
  VirtualProtect(dtex,sizeof*dtex,oldprot[1],oldprot+1);
  dt->restore(dt_buf);
  VirtualProtect(dt,sizeof*dt,oldprot[0],oldprot);
  ExitProcess(0);
}

/*
Ergebnis: Die Funktion DrawText (Static) oder DrawTextEx (MessageBox) wird nur bei wirksamem Manifest aufgerufen!
Für den Allgemeinfall nützt das also nichts,
man muss die Fensterklassen "Static" und "Button" bei Bedarf sub- oder superklassifizieren.
Offenbar ruft die User-Implementierung (der Fensterklassen Static und DialogBox) irgendetwas internes auf.
*/
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded