program tiny_bug; //{$DEFINE _DEBUG} {$IFNDEF _DEBUG} {$A+,B-,C-,D-,E-,F-,G+,H+,I-,J-,K-,L-,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y-,Z1} {$MINSTACKSIZE $00004000} {$MAXSTACKSIZE $00100000} {$IMAGEBASE $00400000} {$APPTYPE GUI} {$ENDIF} {$DEFINE TINY_BUG} {$IFDEF TINY_BUG} {$DEFINE GRID_TRANS} //大して変わらない {$DEFINE GRID_SUB} {$DEFINE SETTINGFILE} //コメントアウトするとファイルサイズが1KB減る {$DEFINE COPY} {$DEFINE COPYSENDTO} //コピー後関連付けされたプログラムへ作業ファイルを渡して起動 {$DEFINE HELP} //バージョン情報 {$DEFINE HELPONLINE} //オンラインヘルプ {$ENDIF} { puffbitsからbugseyeに改名。 その後軽量シンプルなものをということで元のpuffbitsの名を借り派生。 その後更に軽量シンプルなものを目指してLenZoom作成。 更に更にLenZoomのAPIでの書き換えのための習作としてTiny-BUGと命名して作成。 習作から発展して極小ファイルサイズを狙って機能をガンガン削りコードも削り30KB台を 実現。 その後一時停止時にドラッグして移動等の機能追加を重ねたもののファイルサイズが50KB 程度にまで増えそうな気配だったため原点回帰ということで機能を絞ったり色々工夫を重 ねた結果30KBに抑えるに至る。 また 2016-10-24:Ver 1.0.8.151 ・高DPI環境でのスケーリング時の不具合を修正。 ※ストイック版  25KBに増量。 2011-07-12:Ver 1.0.7.131 ※通常版 ・アイコン変更。 ・「コピー」に「幅」と「高さ」を追加。 ・エクスプローラの「プロパティ」→「バージョン情報」の表示情報を削除。  コピーに幅と高さを追加したため30KBに増えたのでプログラムサイズを削るため。 ※ストイック版 ・アイコン削除。 ・コピー機能削除。 アイコンとコピー機能を削除したことで24KBに減った。   2011-06-27:Ver 1.0.6.131 ・グリッドを引く倍率未満の時のカーソル位置を表すボックスの幅が1ピクセル大きかった  不具合を修正。 ※通常版 ・「常に前面に表示」オプションを設定ファイルに持つようにした。 ・オンラインヘルプ機能実装。 ・[Ctrl]+コピーでコピーする文字列をテキストファイルに保存し関連付けられたプログ  ラムに渡して起動できるようにした。 ※ストイック版 ・サブグリッド機能を削除してコンパイル。 その他コードの見直しと合わせてファイルサイズが26KBに。 2011-06-25:Ver 1.0.5.116 ・タイトルバーを表示するように変更。 ※通常版 ・設定ファイル名を'setting.dat'から'tiny_bug.dat'に変更。 ※ストイック版 ・「プロジェクトオプション」→「バージョン情報」の「バージョン番号を含める」の  チェックを外すことで500B程度小さくなる。 ・設定ファイルを作らない条件コンパイル指定を追加。  設定ファイルを作らないようにコンパイルするとファイルサイズが1KB小さくなる。 ・ヘルプを表示しない条件コンパイル指定を追加。  500B程度小さくなる。 結果ストイック版としては27KBのファイルサイズになった。 2011-06-11:Ver 1.0.4.116 ・Unicode非対応に変更。  9x系OSでも動くように。 ・設定ファイル名を起動ファイル名+'bin'から'setting.dat'に固定。 ファイルサイズが29KBに減った。 2011-05-10:Ver 1.0.3.103 ・起動時モニターの範囲外にならないように修正。 ・「グリッド表示」「半透明」復活。 ・設定ファイル名をプログラム名+'.bin'と簡易なものにした。  拡張子を'.bin'に変えるとその分コードが増えファイルサイズが増えてしまうので。 モニターの範囲外で起動しないようにしたためファイルサイズが増えてしまった。 その分設定ファイル名を簡易なものにしたためファイルサイズが少し小さくなった。 結果30KB台に収まった。が、エクスプローラ上では31KB。 2011-05-05:Ver 1.0.2.99 ・クリップボードのCF_UNICODE形式へのコピーを廃止。  Unicodeな文字列ではないしということでサイズ縮小のためもあり廃止。 ・グリッドの半透明を削除。  見やすいけれども必要性は薄いということで。 ・サブグリッド復活。  ただし青のみ。 ・コンパイラオプションの範囲チェックやIOチェック、オーバーフローチェックのチェッ  クを外したら1-2KBほどサイズが小さくなった。  結果30KBに収まった。 2011-05-03:Ver 1.0.1.97 ・簡易ヘルプ実装。 ・コピー機能実装。 ・サブグリッド表示機能を削除。 ファイルサイズが31KBに増えた。 2011-04-30:Ver 1.0.0.88 ・何とか形に。 } uses {$IFDEF _DEBUG} myDebug, {$ENDIF} general in 'general.pas'; {$IFDEF TINY_BUG} {$R *.res} {$ENDIF} {$R manifest.res} const G_csFILEVERSION = '1.0.8'; G_csAPP_TITLE = 'T-BUG'; G_csCLASSNAME = 'TApp_TinyBUG'; {$IFDEF SETTINGFILE} FcsSETTINGFILE = 'tiny_bug.dat'; {$ENDIF} {$IFDEF COPYSENDTO} FcsCOPYTEXTFILE = 'tiny_bug.txt'; {$ENDIF} const //メニュー IDM_ZOOM_1 = 1; IDM_ZOOM_2 = 2; IDM_ZOOM_3 = 3; IDM_ZOOM_4 = 4; IDM_ZOOM_6 = 6; IDM_ZOOM_8 = 8; IDM_ZOOM_10 = 10; IDM_ZOOM_12 = 12; IDM_ZOOM_16 = 16; IDM_ZOOM_20 = 20; IDM_GRID_DISP = 101; IDM_GRID_GRAY = 102; IDM_GRID_INVERT = 103; {$IFDEF GRID_TRANS} IDM_GRID_TRANSPARENT = 104; {$ENDIF} {$IFDEF GRID_SUB} IDM_GRID_SUB = 110; {$ENDIF} {$IFDEF COPY} IDM_COPY_RGB_RED = 201; IDM_COPY_RGB_GREEN = 202; IDM_COPY_RGB_BLUE = 203; IDM_COPY_HTML = 204; IDM_COPY_WIDTH = 210; IDM_COPY_HEIGHT = 211; {$ENDIF} // IDM_POS_USER = 301; IDM_CAPTURE_PAUSE = 401; IDM_OPT_STAYONTOP = 501; {$IFDEF HELP} IDM_HELP = 702; {$ENDIF} {$IFDEF HELPONLINE} IDM_HELPONLINE = 703; {$ENDIF} // IDM_MINIMIZE = 701; IDM_EXIT = 700; const //マウスを動かしていない時であっても画面更新を行う時間(ミリ秒) F_ciCAPTURE_REFLESHTIME = 1000; F_ciTIMERCODE = 8345; FciMINGRID = 3; //グリッドを引く最低倍率 FciMINSIZE = 50; //描画領域の最小の高さ&フォームの幅 FciINFOROWCOUNT = 3; //情報表示用に確保する行の数 type T_SaveInfo = packed record szWindow : TMyBounds; iZoom : Shortint; bGridDisp : Boolean; iGrid : UINT; bGridSubDisp : Boolean; //サブグリッドなしでも必要 bStayOnTop : Boolean; end; T_GridInfo = record GridColor : COLORREF; //グリッドの色 GridRop : Integer; //グリッドの線の引き方(通常、反転、半透明) end; T_ColorInfo = record iRed, iGreen, iBlue : Byte; iColor : COLORREF; end; var F_SaveInfo : T_SaveInfo; F_GridInfo : T_GridInfo; //グリッドの色情報 F_ColorInfo : T_ColorInfo; F_hPopupMenu : HMENU; F_hZoomMenu : HMENU; F_hGridMenu : HMENU; F_hCopyMenu : HMENU; F_dcDesktop : HDC; F_dcDraw : HDC; F_bSizing : Boolean; F_bTimer : Boolean; F_iPassTime : DWORD; F_szClient : TMyBounds; //クライアントエリアのサイズ F_szDesktop : TMyBounds; //拡大元になる矩形のサイズ F_szZoom : TMyBounds; //拡大後の矩形サイズ F_ptUser : TPoint; //ユーザー指定座標の原点(表示は座標と幅と高さ) F_rcInfo : TRect; //情報表示領域 F_FontSize : TSize; //文字('0')の幅と高さ F_iHGrid : Integer; //グリッドの数、横方向 F_iVGrid : Integer; //グリッドの数、縦方向 F_ptMousePos : TPoint; F_ptColorPos : TPoint; //カラー情報を取得する描画面の位置(デスクトップの位置ではない) //ドラッグで移動 F_ptMove : TPoint; F_ptScreen : TPoint; F_bMove : Boolean; F_rcCashDesktopRect : TRect; //デスクトップの大きさ (* //デスクトップ //BugsEyeやpuffbitsと違い定点キャプチャはないので一時停止時のみ必要 F_rcCashDesktopRect : TRect; //デスクトップの大きさ F_rgCashDesktopRegion : HRGN; //デスクトップのリージョン F_rcCashMonitorsRect : array of TRect; *) procedure F_SetZoom(iItemID : UINT); forward; procedure F_SetGrid(iItemID : UINT); forward; (* //--- F_GetMonitorItems --- function lfnbEnumMonitorsProc(hHandle: HMONITOR; dc: HDC; r: PRect; lParam : LPARAM): BOOL; stdcall; function lfni_Min(iNum1, iNum2 : Integer) : Integer; begin if (iNum1 <= iNum2) then begin Result := iNum1; end else begin Result := iNum2; end; end; function lfni_Max(iNum1, iNum2 : Integer) : Integer; begin if (iNum1 >= iNum2) then begin Result := iNum1; end else begin Result := iNum2; end; end; var lrg_Rgn : HRGN; // li_Ret : Integer; begin SetLength(F_rcCashMonitorsRect, Length(F_rcCashMonitorsRect) +1); F_rcCashMonitorsRect[High(F_rcCashMonitorsRect)] := r^; SetRect(F_rcCashDesktopRect, lfni_Min(F_rcCashDesktopRect.Left, r^.Left), lfni_Min(F_rcCashDesktopRect.Top, r^.Top), lfni_Max(F_rcCashDesktopRect.Right, r^.Right), lfni_Max(F_rcCashDesktopRect.Bottom, r^.Bottom) ); lrg_Rgn := CreateRectRgnIndirect(r^); try {li_Ret :=} CombineRgn(F_rgCashDesktopRegion, F_rgCashDesktopRegion, lrg_Rgn, RGN_OR); finally DeleteObject(lrg_Rgn); end; Result := True; end; procedure InitMonitorInfo; //デスクトップの大きさ(各モニターの領域の総和)とリージョンをセット。 begin F_rcCashMonitorsRect := nil; SetRect(F_rcCashDesktopRect, 0, 0, 0, 0); DeleteObject(F_rgCashDesktopRegion); F_rgCashDesktopRegion := CreateRectRgnIndirect(F_rcCashDesktopRect); //空のリージョンを作成 EnumDisplayMonitors(0, nil, @lfnbEnumMonitorsProc, 0); OffsetRgn(F_rgCashDesktopRegion, -F_rcCashDesktopRect.Left, -F_rcCashDesktopRect.Top); end; *) procedure SetDCSize(dc : HDC; iWidth, iHeight : Integer); var ldc_Desktop : HDC; lbm_Bmp : HBITMAP; begin ldc_Desktop := GetDC(0); try lbm_Bmp := CreateCompatibleBitmap(ldc_Desktop, iWidth, iHeight); finally ReleaseDC(0, ldc_Desktop); end; DeleteObject(SelectObject(dc, lbm_Bmp)); end; function F_GetPointShift: Integer; begin // if (gfnbIsMenuChecked(F_hGridMenu, IDM_GRID_DISP)) and (F_SaveInfo.iZoom >= FciMINGRID) then begin if (F_GridInfo.GridRop <> R2_NOP) and (F_SaveInfo.iZoom >= FciMINGRID) then begin Result := 2; //グリッドの線を避けるため1ドット足して2 end else begin //※グリッドとカーソルボックスの線の引き方は違っている Result := 1; //グリッド表示がないので1ですむ end; end; procedure F_Capture; { procedure lpc_TextOut(sText : AnsiString; var iTop : Integer); begin TextOutA(F_dcDraw, 1, iTop, PAnsiChar(sText), Length(sText)); Inc(iTop, F_FontSize.cy); end; } const {$IFDEF GRID_SUB} lci_SUBGRID = 5; //サブグリッドの間隔 {$ENDIF} lci_GRIDMARGIN = 1; //倍率が低いときのグリッドとカーソルポイントとの間隔 var lpt_Pos : TPoint; lrc_Rect : TRect; ldc_Desktop : HDC; li_NowTime : DWORD; i : Integer; {$IFDEF GRID_SUB} li_ShiftLine : Integer; {$ENDIF} li_BoxLen : Integer; li_Width : Integer; li_Height : Integer; lh_Pen : HPEN; li_ColorRef : COLORREF; ls_Info : AnsiString; li_Top : Integer; begin if (F_bTimer) // or (F_bSizing) // or (gfnbIsMenuChecked(F_hPopupMenu, IDM_CAPTURE_PAUSE)) then begin Exit; end; F_bTimer := True; if not(gfnbIsMenuChecked(F_hPopupMenu, IDM_CAPTURE_PAUSE)) then begin lpt_Pos := gfnptMousePosGet; // GetCursorPos(lpt_Pos); end; li_NowTime := GetTickCount; if (lpt_Pos.X <> F_ptMousePos.X) or (lpt_Pos.Y <> F_ptMousePos.Y) //前回表示の時と今回とマウスカーソルの位置が違っている or (F_iPassTime = 0) //経過時間が0である or (Abs(li_NowTime - F_iPassTime) > F_ciCAPTURE_REFLESHTIME) //前回描画時からリフレッシュ時間を過ぎている。 then begin //上記のどれかに合致したら処理に入る if (gfnbIsMenuChecked(F_hPopupMenu, IDM_CAPTURE_PAUSE)) then begin SetRect(lrc_Rect, 0, 0, F_szClient.Width, F_szClient.Height); FillRect(F_dcDraw, lrc_Rect, GetStockObject(BLACK_BRUSH)); StretchBlt( F_dcDraw, 0, 0, F_szZoom.Width, F_szZoom.Height, F_dcDesktop, F_ptMousePos.X - F_szDesktop.Left - F_rcCashDesktopRect.Left, F_ptMousePos.Y - F_szDesktop.Top - F_rcCashDesktopRect.Top, F_szDesktop.Width, F_szDesktop.Height, SRCCOPY ); end else begin F_ptMousePos := lpt_Pos; SetRect(lrc_Rect, 0, 0, F_szDesktop.Width, F_szDesktop.Height); FillRect(F_dcDesktop, lrc_Rect, GetStockObject(BLACK_BRUSH)); ldc_Desktop := GetDC(0); try //レイヤードウィンドウはStretchBltでは拡大コピーできないようなので一度等倍でコピーしてから拡大する BitBlt(F_dcDesktop, 0, 0, F_szDesktop.Width, F_szDesktop.Height, ldc_Desktop, F_ptMousePos.X - F_szDesktop.Left, F_ptMousePos.Y - F_szDesktop.Top, SRCCOPY or CAPTUREBLT); StretchBlt(F_dcDraw, 0, 0, F_szZoom.Width, F_szZoom.Height, F_dcDesktop, 0, 0, F_szDesktop.Width, F_szDesktop.Height, SRCCOPY); finally ReleaseDC(0, ldc_Desktop); end; end; //ペンをセット lh_Pen := CreatePen(PS_SOLID, 1, F_GridInfo.GridColor); DeleteObject(SelectObject(F_dcDraw, lh_Pen)); //グリッド描画 if (gfnbIsMenuChecked(F_hGridMenu, IDM_GRID_DISP)) then begin SetRop2(F_dcDraw, F_GridInfo.GridRop); if (F_SaveInfo.iZoom >= FciMINGRID) then begin //縦線を引く for i := 1 to F_iHGrid do begin li_Width := i * F_SaveInfo.iZoom; MoveToEx(F_dcDraw, li_Width, 0, nil); LineTo (F_dcDraw, li_Width, F_rcInfo.Top); end; //横線を引く for i := 1 to F_iVGrid do begin li_Height := i * F_SaveInfo.iZoom; MoveToEx(F_dcDraw, 0, li_Height, nil); LineTo (F_dcDraw, F_szClient.Width, li_Height); end; {$IFDEF GRID_SUB} //サブグリッドを引く if (F_SaveInfo.bGridSubDisp) then begin lh_Pen := CreatePen(PS_SOLID, 1, $FF0000); DeleteObject(SelectObject(F_dcDraw, lh_Pen)); SetRop2(F_dcDraw, R2_COPYPEN); //縦線を引く //キャプチャポイントを中心にしてサブグリッドを引くため li_ShiftLine := ((gfniRound(F_iHGrid / 2) -1) mod lci_SUBGRID) * F_SaveInfo.iZoom; for i := 0 to F_iHGrid div lci_SUBGRID do begin li_Width := li_ShiftLine + (i * F_SaveInfo.iZoom * lci_SUBGRID); MoveToEx(F_dcDraw, li_Width, 0, nil); LineTo (F_dcDraw, li_Width, F_rcInfo.Top); end; //横線を引く //キャプチャポイントを中心にしてサブグリッドを引くため li_ShiftLine := ((gfniRound(F_iVGrid / 2) -1) mod lci_SUBGRID) * F_SaveInfo.iZoom; for i := 0 to F_iVGrid div lci_SUBGRID do begin li_Height := li_ShiftLine + (i * F_SaveInfo.iZoom * lci_SUBGRID); MoveToEx(F_dcDraw, 0, li_Height, nil); LineTo (F_dcDraw, F_szClient.Width, li_Height); end; end; {$ENDIF} end else begin //倍率が低くてグリッドを引けないのでキャプチャポイントのグリッドだけ引く {$IFDEF GRID_SUB} if (F_SaveInfo.bGridSubDisp) then begin //サブグリッドあり lh_Pen := CreatePen(PS_SOLID, 1, $FF0000); DeleteObject(SelectObject(F_dcDraw, lh_Pen)); SetRop2(F_dcDraw, R2_COPYPEN); end; {$ENDIF} //縦線を引く MoveToEx(F_dcDraw, F_ptColorPos.X, 0, nil); LineTo (F_dcDraw, F_ptColorPos.X, F_ptColorPos.Y - F_GetPointShift - lci_GRIDMARGIN); MoveToEx(F_dcDraw, F_ptColorPos.X, F_ptColorPos.Y + F_SaveInfo.iZoom + F_GetPointShift + lci_GRIDMARGIN, nil); LineTo (F_dcDraw, F_ptColorPos.X, F_rcInfo.Top); //横線を引く MoveToEx(F_dcDraw, 0, F_ptColorPos.Y, nil); LineTo (F_dcDraw, F_ptColorPos.X - F_GetPointShift - lci_GRIDMARGIN, F_ptColorPos.Y); MoveToEx(F_dcDraw, F_ptColorPos.X + F_SaveInfo.iZoom + F_GetPointShift + lci_GRIDMARGIN, F_ptColorPos.Y, nil); LineTo (F_dcDraw, F_szClient.Width, F_ptColorPos.Y); end; //現在のマウスカーソルの表示 SetRop2(F_dcDraw, R2_NOT); li_BoxLen := F_SaveInfo.iZoom + F_GetPointShift; li_Width := F_ptColorPos.X - F_GetPointShift; li_Height := F_ptColorPos.Y - F_GetPointShift; MoveToEx(F_dcDraw, li_Width, li_Height, nil); LineTo (F_dcDraw, li_Width + li_BoxLen, li_Height); //→ LineTo (F_dcDraw, li_Width + li_BoxLen, li_Height + li_BoxLen); //↓ LineTo (F_dcDraw, li_Width , li_Height + li_BoxLen); //← LineTo (F_dcDraw, li_Width , li_Height); //↑ end; //情報表示---------------------------------------------------------------------- FillRect(F_dcDraw, F_rcInfo, GetSysColor(COLOR_WINDOW)); li_ColorRef := GetPixel(F_dcDraw, F_ptColorPos.X, F_ptColorPos.Y); { F_ColorInfo.iRed := li_ColorRef and $0000FF; F_ColorInfo.iGreen := li_ColorRef and $00FF00 div $000100; F_ColorInfo.iBlue := li_ColorRef and $FF0000 div $010000; F_ColorInfo.iColor := (F_ColorInfo.iRed * $010000) + (F_ColorInfo.iGreen * $000100) + F_ColorInfo.iBlue; } F_ColorInfo.iRed := Byte((li_ColorRef shl 16) shr 16); F_ColorInfo.iGreen := Byte((li_ColorRef shl 8) shr 16); F_ColorInfo.iBlue := Byte(li_ColorRef shr 16); F_ColorInfo.iColor := (F_ColorInfo.iRed shl 16) + (F_ColorInfo.iGreen shl 8) + F_ColorInfo.iBlue; li_Top := F_rcInfo.Top + 2; { lpc_TextOut( '#' + gfnsIntTo16Str(F_ColorInfo.iColor, 6, '0') //16進 + ' R=' + gfnsIntTo10Str(F_ColorInfo.iRed) //RGB 赤 + ' G=' + gfnsIntTo10Str(F_ColorInfo.iGreen) //RGB 緑 + ' B=' + gfnsIntTo10Str(F_ColorInfo.iBlue) //RGB 青 ,li_Top ); } ls_Info := '#' + gfnsIntTo16Str(F_ColorInfo.iColor) //16進 + ' R=' + gfnsIntTo10Str(F_ColorInfo.iRed) //RGB 赤 + ' G=' + gfnsIntTo10Str(F_ColorInfo.iGreen) //RGB 緑 + ' B=' + gfnsIntTo10Str(F_ColorInfo.iBlue) //RGB 青 ; TextOutA(F_dcDraw, 1, li_Top, PAnsiChar(ls_Info), Length(ls_Info)); Inc(li_Top, F_FontSize.cy); ls_Info := gfnsIntTo10Str(F_SaveInfo.iZoom) + '倍 ' + '(X=' + gfnsIntTo10Str(F_ptMousePos.X) + ' Y=' + gfnsIntTo10Str(F_ptMousePos.Y) + ')' ; TextOutA(F_dcDraw, 1, li_Top, PAnsiChar(ls_Info), Length(ls_Info)); Inc(li_Top, F_FontSize.cy); ls_Info := 'W=' + gfnsIntTo10Str(Abs(F_ptMousePos.X - F_ptUser.X) +1) + ' H=' + gfnsIntTo10Str(Abs(F_ptMousePos.Y - F_ptUser.Y) +1) + ' (' + gfnsIntTo10Str(F_ptUser.X) + ',' + gfnsIntTo10Str(F_ptUser.Y) + ') [Spc=原点]' ; TextOutA(F_dcDraw, 1, li_Top, PAnsiChar(ls_Info), Length(ls_Info)); F_iPassTime := li_NowTime; end; F_bTimer := False; end; procedure DrawNow; begin if (F_FontSize.cy <= 0) // or (F_bThrough) // or (F_bTimer) // or (F_bSizing) then begin Exit; end; F_iPassTime := 0; //すぐに再描画させたい為に間隔判定用のフラグを0にセットする F_Capture; InvalidateRect(G_hMainHandle, nil, False); end; procedure CalcSize; //ズーム領域調整 function lfnrc_RectMagni(const rcRect: TRect; const fMagni: Extended): TRect; begin SetRect(Result, 0, 0, gfniRoundUp(fMagni * gfniRectWidth(rcRect)), gfniRoundUp(fMagni * gfniRectHeight(rcRect))); end; var lb_Sized : Boolean; li_ShiftColorPos : Integer; li_Height : Integer; lrc_Window : TRect; lrc_Client : TRect; lrc_Screen : TRect; lrc_Zoom : TRect; lrc_Rect : TRect; begin // if (F_FontSize.cy <= 0) if (F_bSizing) then begin Exit; end; F_bSizing := True; //無限ループを避けるため //情報表示枠の高さをセット li_Height := F_FontSize.cy * FciINFOROWCOUNT; GetWindowRect(G_hMainHandle, lrc_Window); lb_Sized := (F_SaveInfo.szWindow.Width <> gfniRectWidth (lrc_Window)) or (F_SaveInfo.szWindow.Height <> gfniRectHeight(lrc_Window)) ; { F_SaveInfo.szWindow := Bounds( lrc_Window.Left, lrc_Window.Top, gfniRectWidth (lrc_Window), gfniRectHeight(lrc_Window) ); } with F_SaveInfo.szWindow do begin Left := lrc_Window.Left; Top := lrc_Window.Top; Width := gfniRectWidth (lrc_Window); Height := gfniRectHeight(lrc_Window); end; if (F_SaveInfo.szWindow.Height - li_Height < FciMINSIZE) then begin F_SaveInfo.szWindow.Height := FciMINSIZE + li_Height; end; if (F_SaveInfo.szWindow.Width < FciMINSIZE) then begin F_SaveInfo.szWindow.Width := FciMINSIZE; end; if (gfniRectWidth (lrc_Window) <> F_SaveInfo.szWindow.Width) or (gfniRectHeight(lrc_Window) <> F_SaveInfo.szWindow.Height) then begin SetWindowPos(G_hMainHandle, 0, 0, 0, F_SaveInfo.szWindow.Width, F_SaveInfo.szWindow.Height, SWP_NOMOVE or SWP_NOZORDER); end; GetClientRect(G_hMainHandle, lrc_Client); { F_szClient := Bounds( 0, 0, gfniRectWidth (lrc_Client), gfniRectHeight(lrc_Client) ); } with F_szClient do begin Left := 0; Top := 0; Width := gfniRectWidth (lrc_Client); Height := gfniRectHeight(lrc_Client); end; with F_rcInfo do begin Left := 0; Right := F_szClient.Width; Bottom := F_szClient.Height; Top := Bottom - li_Height; end; //拡大元の領域 := ズーム表示領域 / 倍率 SetRect(lrc_Rect, 0, 0, F_szClient.Width, F_rcInfo.Top); lrc_Screen := lfnrc_RectMagni(lrc_Rect, 1 / F_SaveInfo.iZoom); //(端数が出ないように調整された)拡大後の領域 lrc_Zoom := lfnrc_RectMagni(lrc_Screen, F_SaveInfo.iZoom); //拡大後の領域情報 with F_szZoom do begin Width := gfniRectWidth (lrc_Zoom); Height := gfniRectHeight(lrc_Zoom); //Left,Top は中心を示すことに注意 Left := gfniRound(Width / 2) -1; Top := gfniRound(Height / 2) -1; //グリッドの数 F_iHGrid := gfniRound(Width / F_SaveInfo.iZoom); F_iVGrid := gfniRound(Height / F_SaveInfo.iZoom); end; //拡大元の領域情報 with F_szDesktop do begin Width := gfniRectWidth (lrc_Screen); Height := gfniRectHeight(lrc_Screen); //Left,Top は中心を示すことに注意 Left := gfniRound(Width / 2) -1; Top := gfniRound(Height / 2) -1; end; //グリッドを引くか引かないかでカラーの値を取る位置が1ドットずれる if (F_GetPointShift > 1) then begin li_ShiftColorPos := 1; //グリッドあり、1ドット右下にずらす end else begin li_ShiftColorPos := 0; //グリッドなし、そのまま end; //カラー取得位置 { F_ptColorPos := Point( (gfniRound(F_iHGrid / 2) -1) * F_SaveInfo.iZoom + li_ShiftColorPos, //X (gfniRound(F_iVGrid / 2) -1) * F_SaveInfo.iZoom + li_ShiftColorPos //Y ); } F_ptColorPos.X := (gfniRound(F_iHGrid / 2) -1) * F_SaveInfo.iZoom + li_ShiftColorPos; F_ptColorPos.Y := (gfniRound(F_iVGrid / 2) -1) * F_SaveInfo.iZoom + li_ShiftColorPos; if not(gfnbIsMenuChecked(F_hPopupMenu, IDM_CAPTURE_PAUSE)) then begin SetDCSize(F_dcDesktop, F_szDesktop.Width, F_szDesktop.Height); end; if (lb_Sized) then begin SetDCSize(F_dcDraw, F_szClient.Width, F_szClient.Height); //情報表示領域も含めての高さを指定しないといけない end; F_bSizing := False; end; {$IFDEF SETTINGFILE} function F_ReadSetting: Boolean; var lh_Handle : THandle; li_BinSize : DWORD; li_Read : DWORD; begin Result := False; //Shift+Ctrl終了で設定を読み込まない。 // if (gfnbKeyState(VK_SHIFT) and gfnbKeyState(VK_CONTROL)) then begin if (BOOL(Hi(GetAsyncKeyState(VK_SHIFT)))) and (BOOL(Hi(GetAsyncKeyState(VK_CONTROL)))) then begin Exit; end; // lh_Handle := gfnhOpenFile(FcsSETTINGFILE, False); lh_Handle := CreateFileA( FcsSETTINGFILE, //ファイル名 GENERIC_READ, //アクセスモード FILE_SHARE_READ or FILE_SHARE_WRITE, //共有モード nil, //セキュリティ OPEN_EXISTING, //作成方法 FILE_ATTRIBUTE_NORMAL, //ファイル属性 0 //テンプレート ); try if (lh_Handle = INVALID_HANDLE_VALUE) then begin Exit; end else begin li_BinSize := SizeOf(T_SaveInfo); Result := ReadFile(lh_Handle, F_SaveInfo, li_BinSize, li_Read, nil); if (li_Read <> li_BinSize) then begin Result := False; end; end; finally CloseHandle(lh_Handle); end; end; procedure F_WriteSetting; var li_ErrMode : UINT; lrc_Window : TRect; lh_Handle : THandle; li_Write : DWORD; begin //Shift+Ctrl終了で設定を書き込まない。 // if (gfnbKeyState(VK_SHIFT) and gfnbKeyState(VK_CONTROL)) then begin if (BOOL(Hi(GetAsyncKeyState(VK_SHIFT)))) and (BOOL(Hi(GetAsyncKeyState(VK_CONTROL)))) then begin Exit; end; li_ErrMode := SetErrorMode(SEM_FAILCRITICALERRORS); try lh_Handle := CreateFileA( FcsSETTINGFILE, //ファイル名 GENERIC_WRITE, //アクセスモード 0, //共有モード nil, //セキュリティ CREATE_ALWAYS, //作成方法 FILE_ATTRIBUTE_NORMAL, //ファイル属性 0 //テンプレート ); if (lh_Handle <> INVALID_HANDLE_VALUE) then begin try GetWindowRect(G_hMainHandle, lrc_Window); F_SaveInfo.szWindow.Left := lrc_Window.Left; F_SaveInfo.szWindow.Top := lrc_Window.Top; F_SaveInfo.bStayOnTop := gfnbIsMenuChecked(F_hPopupMenu, IDM_OPT_STAYONTOP); WriteFile(lh_Handle, F_SaveInfo, SizeOf(F_SaveInfo), li_Write, nil); finally CloseHandle(lh_Handle); end; end; except end; SetErrorMode(li_ErrMode); end; {$ENDIF} procedure F_SetTimer(bEnabled : Boolean); begin if (bEnabled) then begin //タイマーセット SetTimer(G_hMainHandle, F_ciTIMERCODE, 70, nil); end else begin //タイマー解除 KillTimer(G_hMainHandle, F_ciTIMERCODE); end; end; procedure F_Pause; //一時停止 var lb_Pause : Boolean; ldc_Desktop : HDC; begin gpcSetMenuCheckInvert(F_hPopupMenu, IDM_CAPTURE_PAUSE); lb_Pause := gfnbIsMenuChecked(F_hPopupMenu, IDM_CAPTURE_PAUSE); F_SetTimer(not(lb_Pause)); if (lb_Pause) then begin //デスクトップの大きさをセット SetRect( F_rcCashDesktopRect, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_XVIRTUALSCREEN) + GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN) + GetSystemMetrics(SM_CYVIRTUALSCREEN) ); SetDCSize(F_dcDesktop, gfniRectWidth(F_rcCashDesktopRect), gfniRectHeight(F_rcCashDesktopRect)); ldc_Desktop := GetDC(0); try //一時停止中はキャッシュ画像からコピーするのでデスクトップ全体の画像をキャッシュしておく BitBlt( F_dcDesktop, 0, 0, gfniRectWidth (F_rcCashDesktopRect), gfniRectHeight(F_rcCashDesktopRect), ldc_Desktop, F_rcCashDesktopRect.Left, F_rcCashDesktopRect.Top, SRCCOPY or CAPTUREBLT ); finally ReleaseDC(0, ldc_Desktop); end; end else begin CalcSize; end; DrawNow; end; {$IFDEF HELP} procedure F_ShowHelp; var ls_Help : AnsiString; begin ls_Help := // G_csAPP_TITLE + ' ' + G_csFILEVERSION + #13 // + 'http://drang.s4.xrea.com/program/bugseye/tiny_bug/help/' G_csAPP_TITLE + ' Ver:' + G_csFILEVERSION + #13 + #13 + '[F1] バージョン情報' {$IFDEF HELPONLINE} + #13 + '[Shift]+[F1] オンラインヘルプ' {$ENDIF} + #13 + '[Esc] 一時停止' + #13 + '[Space] 長さの原点指定' + #13 + '[PgUp] ズームアップ' + #13 + '[PgDn] ズームダウン' + #13 + '[←][↑][↓][←] マウスカーソル移動 (一時停止時はキャプチャポイントの移動)' + #13 + '[R] コピー/RGBの赤' + #13 + '[G] コピー/RGBの緑' + #13 + '[B] コピー/RGBの青' + #13 + '[H] コピー/HTML' + #13 + '[W] コピー/幅' + #13 + '[T] コピー/高さ' // + #13#13 + 'http://cult-drang.com/program/bugseye/tiny_bug/help/index.html' + #13#13 + 'http://drang.s4.xrea.com/program/bugseye/tiny_bug/help/' ; MessageBoxA(G_hMainHandle, PAnsiChar(ls_Help), G_csAPP_TITLE, MB_OK or MB_SETFOREGROUND); end; {$ENDIF} {$IFDEF HELPONLINE} procedure F_ShowHelpOnline; begin ShellExecuteA( G_hMainHandle, nil, 'http://drang.s4.xrea.com/program/bugseye/tiny_bug/help/', nil, nil, SW_SHOWNORMAL ); end; {$ENDIF} procedure F_SetZoom(iItemID : UINT); var i : Integer; li_ItemID : UINT; begin F_SaveInfo.iZoom := iItemID; for i := 0 to GetMenuItemCount(F_hZoomMenu)-1 do begin li_ItemID := GetMenuItemID(F_hZoomMenu, i); gpcSetMenuCheck(F_hZoomMenu, li_ItemID, (li_ItemID = iItemID)); end; CalcSize; DrawNow; end; procedure F_ZoomUp(iUp : Integer); var i : Integer; li_UpDown : Integer; li_Index : Integer; li_Count : Integer; li_ItemID : UINT; begin if (iUp > 0) then begin li_UpDown := 1; end else begin li_UpDown := -1; end; //メニューの項目数を取得 li_Count := GetMenuItemCount(F_hZoomMenu); //現在チェック状態のメニューのインデックスを取得。 li_Index := 0; for i := 0 to li_Count-1 do begin li_ItemID := GetMenuItemID(F_hZoomMenu, i); if (gfnbIsMenuChecked(F_hZoomMenu, li_ItemID)) then begin li_Index := i; Break; end; end; li_Index := gfniNumLimit(li_Index + li_UpDown, 0, li_Count-1); F_SetZoom(GetMenuItemID(F_hZoomMenu, li_Index)); end; procedure F_SetGrid(iItemID : UINT); begin gpcSetMenuCheckInvert(F_hGridMenu, iItemID); if (iItemID = IDM_GRID_DISP) then begin //グリッド F_SaveInfo.bGridDisp := gfnbIsMenuChecked(F_hGridMenu, IDM_GRID_DISP); {$IFDEF GRID_SUB} end else if (iItemID = IDM_GRID_SUB) then begin //サブグリッド F_SaveInfo.bGridSubDisp := gfnbIsMenuChecked(F_hGridMenu, IDM_GRID_SUB); {$ENDIF} end else begin //グリッド F_SaveInfo.iGrid := iItemID; gpcSetMenuCheck(F_hGridMenu, IDM_GRID_GRAY, iItemID = IDM_GRID_GRAY); gpcSetMenuCheck(F_hGridMenu, IDM_GRID_INVERT, iItemID = IDM_GRID_INVERT); {$IFDEF GRID_TRANS} gpcSetMenuCheck(F_hGridMenu, IDM_GRID_TRANSPARENT, iItemID = IDM_GRID_TRANSPARENT); {$ENDIF} case iItemID of IDM_GRID_GRAY :begin //灰色 F_GridInfo.GridColor := $999999; F_GridInfo.GridRop := R2_COPYPEN; end; IDM_GRID_INVERT :begin //反転 F_GridInfo.GridColor := 0; F_GridInfo.GridRop := R2_NOT; end; {$IFDEF GRID_TRANS} IDM_GRID_TRANSPARENT :begin //半透明 F_GridInfo.GridColor := $CCCCCC; F_GridInfo.GridRop := R2_MASKPEN; end; {$ENDIF} { else begin F_SaveInfo.iGrid := 0; F_GridInfo.GridRop := R2_NOP; end; } end; end; DrawNow; end; {$IFDEF COPY} procedure F_CopyText(iItemID : UINT); var ls_Text : AnsiString; {$IFDEF COPYSENDTO} li_ErrMode : UINT; lh_Handle : THandle; li_Write : DWORD; {$ENDIF} begin case iItemID of IDM_COPY_RGB_RED : ls_Text := gfnsIntTo10Str(F_ColorInfo.iRed); IDM_COPY_RGB_GREEN : ls_Text := gfnsIntTo10Str(F_ColorInfo.iGreen); IDM_COPY_RGB_BLUE : ls_Text := gfnsIntTo10Str(F_ColorInfo.iBlue); IDM_COPY_HTML : ls_Text := gfnsIntTo16Str(F_ColorInfo.iColor); IDM_COPY_WIDTH : ls_Text := gfnsIntTo10Str(Abs(F_ptMousePos.X - F_ptUser.X) +1); IDM_COPY_HEIGHT : ls_Text := gfnsIntTo10Str(Abs(F_ptMousePos.Y - F_ptUser.Y) +1); end; gpcStrToClipboard(ls_Text); {$IFDEF COPYSENDTO} if (BOOL(Hi(GetAsyncKeyState(VK_CONTROL)))) then begin li_ErrMode := SetErrorMode(SEM_FAILCRITICALERRORS); try lh_Handle := CreateFileA( FcsCOPYTEXTFILE, //ファイル名 GENERIC_WRITE, //アクセスモード 0, //共有モード nil, //セキュリティ CREATE_ALWAYS, //作成方法 FILE_ATTRIBUTE_NORMAL, //ファイル属性 0 //テンプレート ); if (lh_Handle <> INVALID_HANDLE_VALUE) then begin try WriteFile(lh_Handle, PAnsiChar(ls_Text)^, Length(ls_Text), li_Write, nil); finally CloseHandle(lh_Handle); end; ShellExecuteA( G_hMainHandle, nil, FcsCOPYTEXTFILE, nil, nil, SW_SHOWNORMAL ); end; except end; SetErrorMode(li_ErrMode); end; {$ENDIF} end; {$ENDIF} procedure MovePoint(iX, iY : Integer); var lpt_Pos : TPoint; lpt_Client : TPoint; // lrc_Rect : TRect; // i : Integer; begin if (F_bMove) then begin //ドラッグして移動 lpt_Client := gfnptMousePosGet; // GetCursorPos(lpt_Client); ScreenToClient(G_hMainHandle, lpt_Client); { lpt_Pos := Point( F_ptScreen.X - gfniRound((lpt_Client.X - F_ptMove.X) / F_SaveInfo.iZoom), F_ptScreen.Y - gfniRound((lpt_Client.Y - F_ptMove.Y) / F_SaveInfo.iZoom) ); } lpt_Pos.X := F_ptScreen.X - gfniRound((lpt_Client.X - F_ptMove.X) / F_SaveInfo.iZoom); lpt_Pos.Y := F_ptScreen.Y - gfniRound((lpt_Client.Y - F_ptMove.Y) / F_SaveInfo.iZoom); end else begin { lpt_Pos := Point( F_ptMousePos.X + iX, F_ptMousePos.Y + iY ); } lpt_Pos.X := F_ptMousePos.X + iX; lpt_Pos.Y := F_ptMousePos.Y + iY; end; //デスクトップの範囲内に収める //マルチモニターの環境でモニターの範囲外に出ないように調整するのはサイズが大きくなるので断念 { F_ptMousePos := Point( // gfniNumLimit(lpt_Pos.X, F_szCashDesktop.Left, F_szCashDesktop.Left + F_szCashDesktop.Width -1), // gfniNumLimit(lpt_Pos.Y, F_szCashDesktop.Top, F_szCashDesktop.Top + F_szCashDesktop.Height -1) gfniNumLimit(lpt_Pos.X, F_rcCashDesktopRect.Left, F_rcCashDesktopRect.Right -1), gfniNumLimit(lpt_Pos.Y, F_rcCashDesktopRect.Top, F_rcCashDesktopRect.Bottom -1) } F_ptMousePos.X := gfniNumLimit(lpt_Pos.X, F_rcCashDesktopRect.Left, F_rcCashDesktopRect.Right -1); F_ptMousePos.Y := gfniNumLimit(lpt_Pos.Y, F_rcCashDesktopRect.Top, F_rcCashDesktopRect.Bottom -1); { //マルチモニターの環境でモニターの範囲外に出ないように調整。 if not(PtInRegion(F_rgCashDesktopRegion, lpt_Pos.X - F_rcCashDesktopRect.Left, lpt_Pos.Y - F_rcCashDesktopRect.Top)) then begin SetRect(lrc_Rect, 0, 0, 0, 0); for i := 0 to High(F_rcCashMonitorsRect) do begin if (PtInRect(F_rcCashMonitorsRect[i], F_ptMousePos)) then begin lrc_Rect := F_rcCashMonitorsRect[i]; Break; end; end; lpt_Pos.X := gfniNumLimit(lpt_Pos.X, lrc_Rect.Left, lrc_Rect.Right -1); lpt_Pos.Y := gfniNumLimit(lpt_Pos.Y, lrc_Rect.Top, lrc_Rect.Bottom -1); end; F_ptMousePos := lpt_Pos; } DrawNow; end; procedure OnDestroy; begin //タイマーを解除 F_SetTimer(False); {$IFDEF SETTINGFILE} //設定ファイル保存 F_WriteSetting; {$ENDIF} DeleteDC(F_dcDraw); DeleteDC(F_dcDesktop); // DeleteObject(F_rgCashDesktopRegion); DestroyMenu(F_hZoomMenu); DestroyMenu(F_hGridMenu); DestroyMenu(F_hCopyMenu); DestroyMenu(F_hPopupMenu); end; function MainWndProc(hWindow: HWND; Msg: UINT; iWParam: WPARAM; iLParam: LPARAM): LRESULT; stdcall; var lr_Msg : TMessage; ps : TPaintStruct; li_X, li_Y : Integer; lpt_Pos : TPoint; begin Result := 0; FillChar(lr_Msg, SizeOf(lr_Msg), 0); with lr_Msg do begin Msg := hWindow; WParam := iWParam; LParam := iLParam; Result := 0; end; case Msg of WM_PAINT :begin //ペイント BeginPaint(hWindow, ps); try BitBlt(ps.hdc, 0, 0, F_szClient.Width, F_szClient.Height, F_dcDraw, 0, 0, SRCCOPY); finally EndPaint(hWindow, ps); end; end; WM_ERASEBKGND :begin Result := 1; end; WM_LBUTTONDOWN :begin //マウスダウン GetCursorPos(F_ptMove); ScreenToClient(G_hMainHandle, F_ptMove); F_bMove := ( gfnbIsMenuChecked(F_hPopupMenu, IDM_CAPTURE_PAUSE) and not(PtInRect(F_rcInfo, F_ptMove)) ); if (F_bMove) then begin F_ptScreen := F_ptMousePos; SetCapture(G_hMainHandle); end else begin SendMessageA(lr_Msg.Msg, WM_SYSCOMMAND, WPARAM(SC_SIZE or 9), 0); end; end; WM_MOUSEMOVE :begin if (F_bMove) then begin MovePoint(0, 0); //引数はダミー end else begin SetCursor(LoadCursorA(0, IDC_ARROW)); end; end; WM_LBUTTONUP :begin ReleaseCapture; F_bMove := False; end; WM_MOUSEWHEEL :begin //マウスホイール F_ZoomUp(TWMMouseWheel(lr_Msg).WheelDelta); end; (* WM_SYSKEYDOWN :begin { if (lr_Msg.WParam = VK_MENU) then begin Result := 1; end else } if (lr_Msg.WParam = VK_F10) then begin F_PopupMenu; end; end; *) WM_KEYDOWN :begin case lr_Msg.WParam of VK_LEFT..VK_DOWN //VK_LEFT,VK_UP,VK_RIGHT,VK_DOWN :begin li_X := 0; li_Y := 0; case lr_Msg.WParam of VK_LEFT : li_X := -1; VK_UP : li_Y := -1; VK_RIGHT : li_X := +1; VK_DOWN : li_Y := +1; end; // if (gfnbKeyState(VK_SHIFT)) then begin if (BOOL(Hi(GetAsyncKeyState(VK_SHIFT)))) then begin li_X := li_X * 10; li_Y := li_Y * 10; end; if (gfnbIsMenuChecked(F_hPopupMenu, IDM_CAPTURE_PAUSE)) then begin MovePoint(li_X, li_Y); end else begin // SetCursorPos(F_ptMousePos.X + li_X, F_ptMousePos.Y + li_Y); // lpt_Pos := gfnptMousePosGet; // SetCursorPos(lpt_Pos.X + li_X, lpt_Pos.Y + li_Y); gfnbSetCursorPos(F_ptMousePos.X + li_X, F_ptMousePos.Y + li_Y); DrawNow; end; end; VK_PRIOR :begin F_ZoomUp(1); end; VK_NEXT :begin F_ZoomUp(-1); end; end; end; WM_KEYUP :begin case lr_Msg.WParam of Ord(' ') :begin //距離測定原点の指定 //GetCursorPos(F_ptUser); F_ptUser := F_ptMousePos; DrawNow; end; {$IFDEF COPY} Ord('R') : F_CopyText(IDM_COPY_RGB_RED); Ord('G') : F_CopyText(IDM_COPY_RGB_GREEN); Ord('B') : F_CopyText(IDM_COPY_RGB_BLUE); Ord('H') : F_CopyText(IDM_COPY_HTML); Ord('W') : F_CopyText(IDM_COPY_WIDTH); Ord('T') : F_CopyText(IDM_COPY_HEIGHT); {$ENDIF} VK_ESCAPE :begin //一時停止 F_Pause; end; VK_F1 :begin {$IFDEF HELPONLINE} //オンラインヘルプあり {$IFDEF HELP} if (BOOL(Hi(GetAsyncKeyState(VK_SHIFT)))) then begin F_ShowHelpOnline; end else begin F_ShowHelp; end; {$ELSE} F_ShowHelpOnline; {$ENDIF} {$ELSE} //オンラインヘルプなし //バージョン情報あり {$IFDEF HELP} F_ShowHelp; {$ENDIF} {$ENDIF} end; end; end; WM_CONTEXTMENU :begin //ポップアップメニュー GetCursorPos(lpt_Pos); TrackPopupMenu(F_hPopupMenu, 0, lpt_Pos.X, lpt_Pos.Y, 0, G_hMainHandle, nil); end; WM_COMMAND :begin if (lr_Msg.WParamHi = 0) then begin // Menu=0,Accel=1,NotifyCode=Control case lr_Msg.WParamLo of IDM_ZOOM_1..IDM_ZOOM_20 :begin F_SetZoom(lr_Msg.WParamLo); end; IDM_GRID_DISP, IDM_GRID_INVERT, {$IFDEF GRID_TRANS} IDM_GRID_TRANSPARENT, {$ENDIF} {$IFDEF GRID_SUB} IDM_GRID_SUB, {$ENDIF} IDM_GRID_GRAY :begin F_SetGrid(lr_Msg.WParamLo); end; { IDM_POS_USER :begin //距離測定原点の指定 GetCursorPos(F_ptUser); end; } {$IFDEF COPY} IDM_COPY_RGB_RED..IDM_COPY_HEIGHT :begin F_CopyText(lr_Msg.WParamLo); end; {$ENDIF} IDM_CAPTURE_PAUSE :begin F_Pause; end; IDM_OPT_STAYONTOP :begin gpcSetMenuCheckInvert(F_hPopupMenu, IDM_OPT_STAYONTOP); if (gfnbIsMenuChecked(F_hPopupMenu, IDM_OPT_STAYONTOP)) then begin SetWindowPos(G_hMainHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE); end else begin SetWindowPos(G_hMainHandle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE); end; end; {$IFDEF HELP} IDM_HELP :begin F_ShowHelp; end; {$ENDIF} {$IFDEF HELPONLINE} IDM_HELPONLINE :begin // F_ShowHelpOnline; ShellExecuteA( G_hMainHandle, nil, 'http://drang.s4.xrea.com/program/bugseye/tiny_bug/help/', nil, nil, SW_SHOWNORMAL ); end; {$ENDIF} IDM_EXIT :begin DestroyWindow(G_hMainHandle); end; end; end; end; WM_SIZE :begin if (F_FontSize.cy > 0) then begin CalcSize; DrawNow; end; end; WM_TIMER :begin //タイマー F_Capture; InvalidateRect(G_hMainHandle, nil, False); end; WM_DESTROY :begin OnDestroy; PostQuitMessage(0); end; else begin Result := DefWindowProcA(hWindow, Msg, iWParam, iLParam); end; end; end; procedure OnCreate(hWindow: HWND); var ldc_DC : HDC; begin //メイン F_hPopupMenu := CreatePopupMenu; F_hZoomMenu := CreatePopupMenu; AppendMenuA(F_hPopupMenu, MF_BYPOSITION or MF_POPUP, F_hZoomMenu, 'ズーム(&Z)'); gpcAddMenuRadio(F_hZoomMenu, ' 1倍', IDM_ZOOM_1); gpcAddMenuRadio(F_hZoomMenu, ' 2倍', IDM_ZOOM_2); gpcAddMenuRadio(F_hZoomMenu, ' 3倍', IDM_ZOOM_3); gpcAddMenuRadio(F_hZoomMenu, ' 4倍', IDM_ZOOM_4); gpcAddMenuRadio(F_hZoomMenu, ' 6倍', IDM_ZOOM_6); gpcAddMenuRadio(F_hZoomMenu, ' 8倍', IDM_ZOOM_8); gpcAddMenuRadio(F_hZoomMenu, '10倍', IDM_ZOOM_10); gpcAddMenuRadio(F_hZoomMenu, '12倍', IDM_ZOOM_12); gpcAddMenuRadio(F_hZoomMenu, '16倍', IDM_ZOOM_16); gpcAddMenuRadio(F_hZoomMenu, '20倍', IDM_ZOOM_20); F_hGridMenu := CreatePopupMenu; AppendMenuA(F_hPopupMenu, MF_BYPOSITION or MF_POPUP, F_hGridMenu, 'グリッド(&G)'); AppendMenuA(F_hGridMenu, MF_STRING, IDM_GRID_DISP, 'グリッド(&G)'); AppendMenuA(F_hGridMenu, MF_SEPARATOR, 0, '-'); gpcAddMenuRadio(F_hGridMenu, '灰色(&G)', IDM_GRID_GRAY); gpcAddMenuRadio(F_hGridMenu, '反転色(&I)', IDM_GRID_INVERT); {$IFDEF GRID_TRANS} gpcAddMenuRadio(F_hGridMenu, '半透明(&T)', IDM_GRID_TRANSPARENT); {$ENDIF} {$IFDEF GRID_SUB} AppendMenuA(F_hGridMenu, MF_SEPARATOR, 0, '-'); AppendMenuA(F_hGridMenu, MF_STRING, IDM_GRID_SUB, 'サブグリッド(&S)'); {$ENDIF} F_hCopyMenu := CreatePopupMenu; {$IFDEF COPY} AppendMenuA(F_hPopupMenu, MF_BYPOSITION or MF_POPUP, F_hCopyMenu, 'コピー(&C)'); AppendMenuA(F_hCopyMenu, MF_STRING, IDM_COPY_RGB_RED, 'RGB - 赤(&R)'); AppendMenuA(F_hCopyMenu, MF_STRING, IDM_COPY_RGB_GREEN, 'RGB - 緑(&G)'); AppendMenuA(F_hCopyMenu, MF_STRING, IDM_COPY_RGB_BLUE, 'RGB - 青(&B)'); AppendMenuA(F_hCopyMenu, MF_STRING, IDM_COPY_HTML, 'HTML(&H)'); AppendMenuA(F_hCopyMenu, MF_SEPARATOR, 0, '-'); AppendMenuA(F_hCopyMenu, MF_STRING, IDM_COPY_WIDTH, '幅(&W)'); AppendMenuA(F_hCopyMenu, MF_STRING, IDM_COPY_HEIGHT, '高さ(&T)'); {$ENDIF} AppendMenuA(F_hPopupMenu, MF_SEPARATOR, 0, '-'); // AppendMenuA(F_hPopupMenu, MF_STRING, IDM_POS_USER, '距離測定原点セット[Space]'); AppendMenuA(F_hPopupMenu, MF_STRING, IDM_CAPTURE_PAUSE, '一時停止(&P)'); AppendMenuA(F_hPopupMenu, MF_STRING, IDM_OPT_STAYONTOP, '常に前面に表示(&T)'); {$IFDEF HELP} AppendMenuA(F_hPopupMenu, MF_SEPARATOR, 0, '-'); AppendMenuA(F_hPopupMenu, MF_STRING, IDM_HELP, 'バージョン情報(&V)'); {$ENDIF} {$IFDEF HELPONLINE} {$IFNDEF HELP} AppendMenuA(F_hPopupMenu, MF_SEPARATOR, 0, '-'); {$ENDIF} AppendMenuA(F_hPopupMenu, MF_STRING, IDM_HELPONLINE, 'オンラインヘルプ(&H)'); {$ENDIF} AppendMenuA(F_hPopupMenu, MF_SEPARATOR, 0, '-'); AppendMenuA(F_hPopupMenu, MF_STRING, IDM_EXIT, '終了(&X)'); DrawMenuBar(F_hPopupMenu); //このブロックを後ろにもって行くと起動時ブラックアウトする ldc_DC := GetDC(hWindow);// CreateDC('Display', nil, nil, nil); try F_dcDesktop := CreateCompatibleDC(ldc_DC); F_dcDraw := CreateCompatibleDC(ldc_DC); finally ReleaseDC(hWindow, ldc_DC); end; SelectObject(F_dcDraw, GetStockObject(DEFAULT_GUI_FONT)); FillChar(F_FontSize, SizeOf(F_FontSize), 0); GetTextExtentPoint32A(F_dcDraw, '0', 1, F_FontSize); Inc(F_FontSize.cy, 2); //上下1ピクセルずつ増やす SetTextColor(F_dcDraw, GetSysColor(COLOR_WINDOWTEXT)); SetBkColor (F_dcDraw, GetSysColor(COLOR_WINDOW)); F_SetZoom(UINT(F_SaveInfo.iZoom)); //グリッド gpcSetMenuCheck(F_hGridMenu, IDM_GRID_DISP, F_SaveInfo.bGridDisp); {$IFDEF GRID_SUB} //サブグリッド gpcSetMenuCheck(F_hGridMenu, IDM_GRID_SUB, F_SaveInfo.bGridSubDisp); {$ENDIF} //グリッド適用 F_SetGrid(F_SaveInfo.iGrid); {$IFDEF SETTINGFILE} if (F_SaveInfo.bStayOnTop) then begin //常に前面に表示のセット MainWndProc(G_hMainHandle, WM_COMMAND, IDM_OPT_STAYONTOP, 0); end; {$ENDIF} //タイマーセット F_SetTimer(True); end; //------------------------------------------------------------------------------ {$IFDEF SETTINGFILE} function EnumMonitorsProc(hHandle: HMONITOR; dc: HDC; r: PRect; pInside : PBoolean): BOOL; stdcall; var lrc_Rect : TRect; lrc_Window : TRect; begin SetRect( lrc_Window, F_SaveInfo.szWindow.Left, F_SaveInfo.szWindow.Top, F_SaveInfo.szWindow.Left + F_SaveInfo.szWindow.Width, F_SaveInfo.szWindow.Top + F_SaveInfo.szWindow.Height ); if (IntersectRect(lrc_Rect, r^, lrc_Window)) then begin pInside^ := True; Result := False; end else begin Result := True; end; end; {$ENDIF} //main var l_WndClass : TWndClassA; l_Msg : TMsg; {$IFDEF SETTINGFILE} lb_Inside : Boolean; {$ENDIF} begin {$IFDEF _DEBUG} myDebug.gpcMessageModeSet(True); {$ENDIF} with l_WndClass do begin style := CS_VREDRAW or CS_HREDRAW or CS_OWNDC; lpfnWndProc := @MainWndProc; // cbClsExtra := 0; // cbWndExtra := 0; hInstance := SysInit.HInstance; {$IFDEF TINY_BUG} hIcon := LoadIconA(hInstance, 'MAINICON'); {$ENDIF} // hCursor := 0; // hbrBackground := CreateSolidBrush(GetSysColor(COLOR_WINDOW)); hbrBackground := GetStockObject(WHITE_BRUSH); // lpszMenuName := nil; lpszClassName := G_csCLASSNAME; end; if (RegisterClassA(l_WndClass) = 0) then begin Halt(1); end; {$IFDEF SETTINGFILE} if (F_ReadSetting) then begin //モニター外で起動しないようにするため lb_Inside := False; EnumDisplayMonitors(0, nil, @EnumMonitorsProc, LPARAM(@lb_Inside)); if not(lb_Inside) then begin //モニター範囲外 F_SaveInfo.szWindow.Left := 0; F_SaveInfo.szWindow.Top := 0; end; end else begin with F_SaveInfo.szWindow do begin Left := 75; Top := 75; Width := Left + 140; Height := Top + 160; end; F_SaveInfo.iZoom := IDM_ZOOM_6; F_SaveInfo.bGridDisp := True; F_SaveInfo.iGrid := IDM_GRID_GRAY; F_SaveInfo.bGridSubDisp := True; end; {$ELSE} // F_SaveInfo.szWindow := Bounds(75, 75, 75 + 140, 75 + 160); with F_SaveInfo.szWindow do begin Left := 75; Top := 75; Width := Left + 140; Height := Top + 160; end; F_SaveInfo.iZoom := IDM_ZOOM_6; F_SaveInfo.bGridDisp := True; F_SaveInfo.iGrid := IDM_GRID_GRAY; {$IFDEF GRID_SUB} F_SaveInfo.bGridSubDisp := True; {$ENDIF} {$ENDIF} G_hMainHandle := CreateWindowExA( 0, G_csCLASSNAME, {$IFDEF HELP} G_csAPP_TITLE, {$ELSE} // G_csAPP_TITLE + ' Ver:' + G_csFILEVERSION, G_csAPP_TITLE + ' ' + G_csFILEVERSION, {$ENDIF} WS_VISIBLE or WS_POPUP or WS_SYSMENU or WS_MINIMIZEBOX or WS_CAPTION or WS_THICKFRAME , F_SaveInfo.szWindow.Left, F_SaveInfo.szWindow.Top, F_SaveInfo.szWindow.Width, F_SaveInfo.szWindow.Height, 0, 0, SysInit.HInstance, nil ); if (G_hMainHandle = 0) then begin Halt(1); end; F_SaveInfo.szWindow.Width := 0; //CalcSizeでF_dcDrawの初期化をするために必要 OnCreate(G_hMainHandle); while (GetMessageA(l_Msg, 0, 0, 0)) do begin DispatchMessageA(l_Msg); end; //タスクバーのプロセスタブからプロセスの終了などで終了させるとここには来ない DestroyWindow(G_hMainHandle); Halt(l_Msg.wParam); end.