⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unawinclasses.pas

📁 Voice Commnucation Components for Delphi
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    function onDrawFrame(): bool; virtual;
    function onRunEnterLeave(enter: bool): bool; override;
    function doCreateWindow(): hWnd; override;
    procedure skipFrame();
  public
    constructor create(fps: unsigned = 20; frameWidth: unsigned = 700; frameHeight: unsigned = 500; bgColor: COLORREF = 0; const title: string = ''; canResize: bool = true; canMinimize: bool = true; x: int = 50; y: int = 20; icon: int = -1; windowFlags: int = -1; windowExFlags: int = -1; memWidth: int = -1; memHeight: int = -1); overload;
    constructor create(wnd: hWnd; fps: unsigned = 20; bgColor: COLORREF = 0; const title: string = ''; canResize: bool = true; memWidth: int = -1; memHeight: int = -1); overload;
    destructor Destroy(); override;
    //
    function setBits(x, y: int; data: pointer; size: unsigned): unsigned;
    //
    property grDC: hDC read f_grDC;
    property memDC: hDC read f_memDC;
    //
    property memDIB: hBITMAP read f_memDIB;
    property memDIBInfo: BITMAPINFO read f_memBmpInfo;
    property memXSize: int read f_memXSize;
    property memYSize: int read f_memYSize;
    //
    property fps: unsigned read f_fps;
    property actualFps: unsigned read f_actualFps;
    property frameWidth: unsigned read f_frameWidth;
    property frameHeight: unsigned read f_frameHeight;
    property bgColor: unsigned read f_bgColor;
    //
    property eraseBg: bool read f_eraseBg write f_eraseBg;
  end;


  //
  // -- unaWinBitmap --
  //
  {DP:CLASS
    Windows bitmap.
  }
  unaWinBitmap = class
  private
    //f_bitmap: hBITMAP;
    //f_dc: hDC;
  public
  end;


const
  btnCmdExit	= 1004;
  btnCmdStart	= 1005;
  btnCmdStop	= 1006;

  btnCmdFirstAvail	= 1100;

type
  //
  // -- unaWinConsoleApp --
  //
  {DP:CLASS
    Simple console-like application main window class.
  }
  unaWinConsoleApp = class(unaWinApp)
  private
    f_ini: unaIniAbstractStorage;
    f_memo: unaWinMemo;
    f_btnExit: unaWinButton;
    f_btnStart: unaWinButton;
    f_btnStop: unaWinButton;
    f_captionHeight: unsigned;
    f_hasGUI: bool;
    //
  protected
    {DP:METHOD
      WM_COMMAND message handler. cmd values below 10 are reserved for internal usage.
    }
    function onCommand(cmd, wnd: int): bool; override;
    {DP:METHOD
      WM_DESTROY message handler.
    }
    function onDestroy(): bool; override;
    {DP:METHOD
      Called on the start of application.
    }
    procedure onStart(); virtual;
    {DP:METHOD
      Called on the end of application.
    }
    procedure onStop(); virtual;
    {DP:METHOD
      This method can be used to perform additional initialization.
    }
    function doInit(): bool; virtual;
    {DP:METHOD
      This method is used to display "console" memo messages.
    }
    procedure idle(); override;
  public
    {DP:METHOD
      Creates console-like window.
    }
    constructor create(hasGUi: bool; const caption, copy: string; const iniFile: string = ''; icon: hIcon = 0; captionHeight: unsigned = 32; btnExit: bool = true; btnStart: bool = false; btnStop: bool = false; style: unsigned = WS_OVERLAPPEDWINDOW; exStyle: unsigned = WS_EX_CONTROLPARENT);
    {DP:METHOD
    }
    destructor Destroy(); override;
    //
    {DP:METHOD
      Exit button.
    }
    property btnExit: unaWinButton read f_btnExit;
    {DP:METHOD
      Start button.
    }
    property btnStart: unaWinButton read f_btnStart;
    {DP:METHOD
      Stop button.
    }
    property btnStop: unaWinButton read f_btnStop;
    {DP:METHOD
      Height of upper panel with buttons.
    }
    property captionHeight: unsigned read f_captionHeight;
    //
    property hasGUI: bool read f_hasGUI;
  end;


{DP:METHOD
  Returns Windows class encapsulation instance by given class name.
  Class will be created and registered if necessary.
}
// -- getClass() --
function getClass(const className: string = ''; isStdClass: bool =  false; style: unsigned = 0; icon: hIcon = 0; smallIcon: hIcon = 0; cursor: hCursor = 0; brBrush: hBrush = COLOR_WINDOW; menuName: int = 0; instance: hModule = 0; force: bool = true): unaWinClass;


implementation


uses
  unaUtils;

function ChooseFont;  external 'comdlg32.dll'  name 'ChooseFontA';
function ChooseFontA; external 'comdlg32.dll'  name 'ChooseFontA';
function ChooseFontW; external 'comdlg32.dll'  name 'ChooseFontW';

type
  //
  // --  --
  //
  unaWinList = class(unaIdList)
  protected
    function getId(item: pointer): int64; override;
  public
    function callWndProc(index: int; message: int; wParam: int; lParam: int; window: hWnd = 0): int;
  end;


{ unaWinList }

// --  --
function unawinList.callWndProc(index, message, wParam, lParam: int; window: hWnd): int;
var
  w: unaWinWindow;
begin
  w := unaWinWindow(get(index));
  //
  if (nil <> w) then
    result := w.wndProc(message, wParam, lParam)
  else
    result := DefWindowProc(window, message, wParam, lParam);
end;

// --  --
function unaWinList.getId(item: pointer): int64;
begin
  if (nil <> item) then
    result := unaWinWindow(item).wnd
  else
    result := 0;
end;




var
  g_winList: unaWinList;
  g_winCreateClass: unaWinWindow;
  g_winClasses: unaList;
  g_winFonts: unaList;
  g_winCreateGate: unaInProcessGate;

// -- --
function getClass(const className: string; isStdClass: bool; style: unsigned; icon, smallIcon: hIcon; cursor: hCursor; brBrush: hBrush; menuName: int; instance: hModule; force: bool): unaWinClass;
var
  i: unsigned;
begin
  result := nil;
  i := 0;
  //
  if (nil <> g_winClasses) then begin
    //
    while (i < g_winClasses.count) do begin
      //
      result := g_winClasses.get(i);
      if ((0 <> result.atom) or result.isCommon) then begin
	//
	if (result.f_wndClass.lpszClassName = className) then
	  break
	else
	  result := nil;
	//
      end
      else
	result := nil;
      //
      inc(i);
    end;
  end;
  //
  if (nil = result) then
    if (isStdClass) then
      result := unaWinClass.createStdClass(className)
    else
      result := unaWinClass.create(className, style, icon, smallIcon, cursor, brBrush, menuName, instance, force);
end;

// --  --
function unaWndProc(window: hWnd; message, wParam, lParam: int): int; stdcall;
var
  i: int;
  long: unsigned;
begin
  // 1. try to locate this window in our winList
  long := GetWindowLong(window, 0);
  if ($19730000 = long and $FFFF0000) then
    // looks like our window
    i := long and $FFFF
  else
    // could be standard class window
    i := g_winList.locateById(window);

  //
  if (0 > i) then begin
    //
    if (nil <> g_winCreateClass) then begin
      //
      g_winCreateClass.setWinHandle(window);
      //
      i := g_winList.add(g_winCreateClass);
      g_winCreateClass.setWinListIndex(i);
    end;
  end;

  // 2. call wndProc
  if (0 <= i) then
    result := g_winList.callWndProc(i, message, wParam, lParam, window)
  else
    result := DefWindowProc(window, message, wParam, lParam);
end;

// --  --
function unaCreateWindow(window: unaWinWindow): hWnd;
var
  parent: hWnd;
  params: punaWinCreateParams;
begin
  params := window.getCreateParams();
  parent := window.getParent();
  //
  if (g_winCreateGate.enter(1000)) then begin
    //
    try
      g_winCreateClass := window;
      if (params.r_class.isCommon) then
	//
	// subclassing works, but kills standard controls on system dialog boxes, for example
	// I have no time now to investigate what is wrong, so I will disable that, since most
	// importan messages are sent to parent anywhay
	//
	//params.r_class.createSubclass(parent, @unaWndProc);
	;

      result := CreateWindowEx(params.r_exStyle, params.r_class.getWndClass().lpszClassName, pChar(params.r_caption), params.r_style, params.r_x, params.r_y, params.r_width, params.r_height, parent, params.r_menu, 0, nil);
      //
    finally
      g_winCreateClass := nil;
      g_winCreateGate.leave();
    end;
  end
  else
    result := 0;
end;

{ unaWinClass }

// --  --
function unaWinClass.callSubClassedWndProc(window: hWnd; message, wParam, lParam: int): int;
begin
  if (f_wasSubClassed and (0 <> f_oldClassWndProc)) then
    //
    result := CallWindowProc(pointer(f_oldClassWndProc), window, message, wParam, lParam)
  else
    result := -1;
end;

// --  --
class function unaWinClass.classIsRegistered(const className: string; instance: hModule): bool;
var
  info: TWNDCLASS;
begin
  result := GetClassInfo(instance, pChar(className), info);
end;

// --  --
constructor unaWinClass.create(const name: string; style: unsigned; icon, smallIcon: hIcon; cursor: hCursor; brBrush: hBrush; menuName: int; instance: hModule; force: bool);
begin
  inherited create();
  //
  if ('' = name) then
    f_name := strNew(className)
  else
    f_name := strNew(name);
  //
  f_wndClass.cbSize := sizeOf(f_wndClass);
  f_wndClass.style := style;
  f_wndClass.lpfnWndProc := @unaWndProc;
  f_wndClass.cbClsExtra := 0;
  f_wndClass.cbWndExtra := 4;	// stores pointer to window (Delphi) class instance
  if (0 = instance) then
    f_wndClass.hInstance := GetModuleHandle(nil)
  else
    f_wndClass.hInstance := instance;
  //
  f_wndClass.hIcon := icon;
  //
  if (0 = cursor) then
    f_wndClass.hCursor := LoadCursor(instance, IDC_ARROW)
  else
    f_wndClass.hCursor := cursor;
  //
  f_wndClass.hbrBackground := brBrush;
  f_wndClass.lpszMenuName := pChar(menuName);
  f_wndClass.lpszClassName := f_name;
  f_wndClass.hIconSm := smallIcon;
  //
  if (nil <> g_winClasses) then
    g_winClasses.add(self);
  //
  registerClass(force);
end;

// --  --
constructor unaWinClass.createStdClass(const name: string; instance: hModule);
begin
  inherited create();
  //
  if (GetClassInfoEx(instance, pChar(name), f_wndClass)) then begin
    //
    f_name := strNew(name);
    f_classOwner := false;
    f_isCommon := true;
  end
  else
    create(name, 0, 0, 0, 0, 0, 0, instance);
  //
  if (nil <> g_winClasses) then
    g_winClasses.add(self);
end;

// --  --
function unaWinClass.createSubclass(mainWnd: hWnd; newWndProc: pointer): bool;
var
  oldProc: int;
begin
  if (not f_wasSubclassed) then begin
    // try to subclass a class

    // 1. create a window of that class
    f_subClassWnd := CreateWindow(f_wndClass.lpszClassName, nil, WS_CHILD, 0, 0, 50, 50, mainWnd, 0, f_wndClass.hInstance, nil);

    if (0 <> f_subClassWnd) then begin
      // 2. check if class is not already subclassed to this wndProc
      oldProc := GetClassLong(f_subClassWnd, GCL_WNDPROC);
      if (int(newWndProc) <> oldProc) then begin

	// 3. do subclass
	f_oldClassWndProc := oldProc;	// just in case some message will be passed while f_oldClassWndProc is not set (i.e. SetClassLong() is not returned)
	f_wasSubClassed := true;
	f_oldClassWndProc := SetClassLong(f_subClassWnd, GCL_WNDPROC, int(newWndProc));
      end
      else
	// remove the window - its class is already subclassed to given wndProc
	DestroyWindow(f_subClassWnd);
    end;
  end;
  //
  result := f_wasSubclassed;
end;

// --  --
destructor unaWinClass.destroy();
begin
  if (nil <> g_winClasses) then
    g_winClasses.removeItem(self);
  //
  inherited;
  //
  removeSubclass();
  //
  if (f_classOwner) then
    unregister();
  //
  mrealloc(f_name);
end;

// --  --
function unaWinClass.getAtom(): ATOM;
begin
  result := registerClass();
end;

// --  --
function unaWinClass.getWndClass(): pWNDCLASSEX;
begin
  result := @f_wndClass;
end;

// --  --
function unaWinClass.registerClass(force: bool): atom;
var
  info: TWNDCLASSEX;
  name: string;
begin
  if (0 = f_atom) then begin
    //
    if (force) then begin
      //
      while (GetClassInfoEx(f_wndClass.hInstance, f_name, info)) do begin
	name := f_name;
	name := name + 'a';
	mrealloc(f_name);
	f_name := strNew(name);
	f_wndClass.lpszClassName := f_name;
      end;
    end;
    //
    result := RegisterClassEx(f_wndClass);
    f_atom := result;
  end
  else
    result := f_atom;
end;

// --  --
procedure unaWinClass.removeSubclass();
begin
  if (f_wasSubclassed) then begin
    // remove the subclass, restore old wndProc
    SetClassLong(f_subClassWnd, GWL_WNDPROC, f_oldClassWndProc);
    // and destroy subclass window
    DestroyWindow(f_subClassWnd);
    //
    f_wasSubclassed := false;
  end;
end;

// --  --
procedure unaWinClass.unregister();
begin
  if ((0 <> f_atom) and not isCommon) then begin
    //
    if (UnregisterClass(pChar(f_atom), f_wndClass.hInstance)) then
      f_atom := 0;
    //  
  end;
end;

{ unaWinFont }

// --  --
class function unaWinFont.chooseScreenFont(var font: LOGFONT; owner: hWnd;
  dc: hDC; flags, sizeMin, sizeMax: unsigned): bool;
var
  cf: TCHOOSEFONT;
begin
  cf.lStructSize := sizeOf(cf);
  cf.hWndOwner := owner;
  cf.hDC := dc;
  cf.lpLogFont := @font;
  cf.iPointSize := 0;
  cf.Flags := flags;
  cf.rgbColors := RGB(0, 0, 0);
  cf.lCustData := 0;
  cf.lpfnHook := nil;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -