■マルコフ連鎖
ただ、酔っ払いがデスクトップにヒョコヒョコって出てきて、何やら言葉が表示されるのを見てると 楽しいです。そう、この言葉がマルコフ連鎖によって作られているとの事です。
(公開されているコードでは、日本語は使えないですけどね)
Zarko's Delphi Programming Blog
Barstool Philosopher - Fancy Delphi Application Contest Entry #5
Wikipedia
マルコフ連鎖
| 固定リンク
| 固定リンク
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if Key = '.' then begin Edit1.Text := Edit1.Text + '000'; Key := #0; Edit1.SelStart := Length(Edit1.Text); end; end;
| 固定リンク
| 固定リンク
| 固定リンク
// ExecuteCommand Entry function PLG_ExecuteCommand(pPlgStruct: PLUGGEDIN_STRUCT): LongInt; stdcall; function GetFileDateTime(const FileName: String; var CreateYMD, LastWriteYMD, LastAccessYMD: TDateTime): Boolean; var Handle: Integer; Time1, Time2, Time3: TFILETIME; SysTime: TSYSTEMTIME; SECURITYATTRIBUTES: TSECURITYATTRIBUTES; begin Result := False; with SECURITYATTRIBUTES do begin nLength := SizeOf(TSECURITYATTRIBUTES); lpSecurityDescriptor := nil; bInheritHandle := False; end; Handle := CreateFile(PChar(FileName),GENERIC_READ,0,@SECURITYATTRIBUTES, OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,0); if Handle = 0 then Exit; try GetFileTime(Handle, @Time1, @Time2, @Time3); FileTimeToLocalFileTime(Time1,Time1); FileTimeToSystemTime(Time1, SysTime); CreateYMD := SystemTimeToDateTime(SysTime); FileTimeToLocalFileTime(Time2,Time2); FileTimeToSystemTime(Time2, SysTime); LastAccessYMD := SystemTimeToDateTime(SysTime); FileTimeToLocalFileTime(Time3,Time3); FileTimeToSystemTime(Time3, SysTime); LastWriteYMD := SystemTimeToDateTime(SysTime); Result := True; finally CloseHandle(Handle); end; end; var I: Integer; S: String; InputFile: String; CreateYMD, LastWriteYMD, LastAccessYMD: TDateTime; begin S := ''; for I := 0 to pPlgStruct^.ps_nFiles-1 do begin InputFile := pPlgStruct^.ps_pszFiles^[I]; if GetFileDateTime(InputFile, CreateYMD, LastWriteYMD, LastAccessYMD) then begin if CreateYMD <= LastWriteYMD then S := FormatDateTime('yyyymmdd', CreateYMD) else S := FormatDateTime('yyyymmdd', LastWriteYMD); S := ExtractFilePath(InputFile) + S + ExtractFileName(InputFile); RenameFile(InputFile, S); end; end; Result := 1; end;上記のコードで、きちんとファイル名を修正してくれるのですが、Docuworks Deskでのファイル位置が 一番最後に移動してしまいます。DocuworksのAPIには、ファイル名の変更をするものがなさそうなので、 解決できずにいます。メッセージでメニューとクリップボードを使って処理する方法もありますが、 スマートじゃないですよね。
| 固定リンク
library Project1; uses Windows, SysUtils; {$R *.res} // xdwapiを使うための宣言--ここから const XDW_OPEN_UPDATE = 1; type XDW_DOCUMENT_HANDLE = record dummy: LongInt; end; XDW_OPEN_MODE = record nSize: Integer; nOption: Integer; end; XDW_DOCUMENT_INFO = record nSize: Integer; nPages: Integer; nVersion: Integer; nOriginalData: Integer; nDocType: Integer; nPermission: Integer; nShowAnnotations: Integer; nDocuments: Integer; nBinderColor: Integer; nBinderSize: Integer; end; function XDW_OpenDocumentHandle(const lpszFilePath: PAnsiChar; var Handle: XDW_DOCUMENT_HANDLE; var OpenMode: XDW_OPEN_MODE): Integer; stdcall; external 'xdwapi.dll'; function XDW_GetDocumentInformation(Handle: XDW_DOCUMENT_HANDLE; var DocumentInfo: XDW_DOCUMENT_INFO): Integer; stdcall; external 'xdwapi.dll'; function XDW_RotatePageAuto(Handle: XDW_DOCUMENT_HANDLE; nPage: Integer; reserved: Pointer=nil): Integer; stdcall; external 'xdwapi.dll'; function XDW_SaveDocument(Handle: XDW_DOCUMENT_HANDLE; reserved: Pointer= nil): Integer; stdcall; external 'xdwapi.dll'; function XDW_CloseDocumentHandle(Handle: XDW_DOCUMENT_HANDLE; reserved: Pointer=nil): Integer; stdcall; external 'xdwapi.dll'; function XDW_Finalize(reserved: Pointer = nil): Integer; stdcall; external 'xdwapi.dll'; // xdwapiを使うための宣言--ここまで // 以下、PLUGINSPI用の処理 const PLUGGEDIN_REGKEY = 'Software\\FujiXerox\\MPM3\\MPWS\\PLUGGEDIN'; MAX_PLUGGEDIN_NUMBER = 30; PLUGGEDIN_VERSION = 2; // PLUGGEDIN_NAME_INITIALIZE = '_PLG_Initialize@4'; PLUGGEDIN_NAME_FINALIZE ='_PLG_Finalize@4'; PLUGGEDIN_NAME_CANFINALIZE = '_PLG_CanFinalize@4'; PLUGGEDIN_NAME_REQUIREFILES = '_PLG_RequireFiles@4'; PLUGGEDIN_NAME_EXECUTECOMMAND = '_PLG_ExecuteCommand@4'; PLUGGEDIN_NAME_ISPARALLEL = '_PLG_IsParallel@4'; PLUGGEDIN_NAME_ISCLONINGCOMMAND = '_PLG_IsCloningCommand@4'; PLUGGEDIN_NAME_GETNEWCLONE = '_PLG_GetNewClone@8'; PLUGGEDIN_NAME_RELEASECLONE = '_PLG_ReleaseClone@4'; PLUGGEDIN_NAME_EXECUTABLE = '_PLG_Executable@8'; PLUGGEDIN_NAME_CANSETPROFILE = '_PLG_CanSetProfile@4'; PLUGGEDIN_NAME_SETPROFILE = '_PLG_SetProfile@4'; PLUGGEDIN_NAME_GETCOMMANDICON = '_PLG_GetCommandIcon@8'; PLUGGEDIN_NAME_ENUMERATECOMMANDS = '_PLG_EnumerateCommands@12'; type Tps_pszFiles = ^_Tps_pszFiles; _Tps_pszFiles = array[0..32767] of PChar; Tps_pnPageNumbers = ^_ps_pnPageNumbers; _ps_pnPageNumbers = array[0..32767] of LongInt; PLUGGEDIN_STRUCT = ^TPluggedin_struct; TPluggedin_struct = packed record ps_nPlugVersion: LongInt; ps_pszFunction: PChar; ps_execParallel: LongInt; ps_nFiles: LongInt; ps_pszFiles: Tps_pszFiles; ps_pnPageNumbers: Tps_pnPageNumbers; ps_pszExecFolder: PChar; ps_hwndDWDesk: LongInt; end; // Initialize Entry function PLG_Initialize(const cmdName: PChar): LongInt; stdcall; begin Result := 1; end; // Finalize Entry function PLG_Finalize(const cmdName: PChar): LongInt; stdcall; begin XDW_Finalize(nil); Result := 1; end; // CanFinalize Entry function PLG_CanFinalize(const cmdName: PChar): LongInt; stdcall; begin Result := 1; end; // RequireFiles Entry function PLG_RequireFiles(const cmdName: PChar): LongInt; stdcall; begin Result := 1; end; // ExecuteCommand Entry function PLG_ExecuteCommand(pPlgStruct: PLUGGEDIN_STRUCT): LongInt; stdcall; const M1 = '自動正立'; M2 = '時間がかかるけどいいの?'; M3 = '終了しました。'; var I,J,K,L,Last_Page: Integer; S: String; h: XDW_DOCUMENT_HANDLE; mode: XDW_OPEN_MODE; info: XDW_DOCUMENT_INFO; InputFile: String; begin Result := 1; if MessageBox(0, PChar(M2), PChar(M1), MB_OKCANCEL) <> 1 Then Exit; // 文書ハンドルを開く mode.nSize := sizeof(XDW_OPEN_MODE); mode.nOption := XDW_OPEN_UPDATE; S := ''; for I := 0 to pPlgStruct^.ps_nFiles-1 do begin //pPlgStruct^.ps_pnPageNumbers[I]; 表示ページ番号 InputFile := pPlgStruct^.ps_pszFiles^[I]; J := XDW_OpenDocumentHandle(PAnsiChar(InputFile), h, mode); try if J > -1 then begin info.nSize := SizeOf(XDW_DOCUMENT_INFO); XDW_GetDocumentInformation(h, info); Last_Page := info.nPages; K := 0; for L := 1 to Last_Page do begin J := XDW_RotatePageAuto(h, L); K := K + J; end; // エラーがない場合に変更内容を保存する if K = 0 then XDW_SaveDocument(h); end; finally // 文書ハンドルを閉じる XDW_CloseDocumentHandle(h); end; end; MessageBox(0, PChar(M3),PChar(M1), MB_OK); Result := 1; end; // IsParallel Entry function PLG_IsParallel(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // IsCloning Entry function PLG_IsCloningCommand(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // GetNewClone Entry function PLG_GetNewClone(cmdName: PChar; nBufSize: LongInt): LongInt; stdcall; begin Result := 0; end; // ReleaseClone Entry function PLG_ReleaseClone(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // Executable Entry function PLG_Executable(const cmdName: PChar; nArgFiles: LongInt): LongInt; stdcall; begin Result := nArgFiles; // ファイルが選択されていない場合には処理させない。 end; // CanSetProfile Entry function PLG_CanSetProfile(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // SetProfile Entry function PLG_SetProfile(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // GetAppIcon Entry function PLG_GetCommandIcon(const cmdName: PChar; bNormalSize: LongInt): HICON; stdcall; begin // 本当はbNormalSize (0,1) により大きなアイコンと小さなものを設定する。 Result:= LoadIcon(hInstance, MAKEINTRESOURCE('MAINICON')); end; // EnumerateCommands Entry function PLG_EnumerateCommands(var cmdNameList: PChar; nBufSize: LongInt; var nBufSizeRequired: LongInt): LongInt; stdcall; const S = '自動正立 by hiderin'; begin nBufSizeRequired := Length(S)+1; if (nBufSize < nBufSizeRequired) then begin Result := 0; Exit; end; StrCopy(@cmdNameList, S); Result := 1; end; exports PLG_INITIALIZE name PLUGGEDIN_NAME_INITIALIZE, PLG_FINALIZE name PLUGGEDIN_NAME_FINALIZE, PLG_CANFINALIZE name PLUGGEDIN_NAME_CANFINALIZE, PLG_REQUIREFILES name PLUGGEDIN_NAME_REQUIREFILES, PLG_EXECUTECOMMAND name PLUGGEDIN_NAME_EXECUTECOMMAND, PLG_ISPARALLEL name PLUGGEDIN_NAME_ISPARALLEL, PLG_ISCLONINGCOMMAND name PLUGGEDIN_NAME_ISCLONINGCOMMAND, PLG_GETNEWCLONE name PLUGGEDIN_NAME_GETNEWCLONE, PLG_RELEASECLONE name PLUGGEDIN_NAME_RELEASECLONE, PLG_EXECUTABLE name PLUGGEDIN_NAME_EXECUTABLE, PLG_CANSETPROFILE name PLUGGEDIN_NAME_CANSETPROFILE, PLG_SETPROFILE name PLUGGEDIN_NAME_SETPROFILE, PLG_GETCOMMANDICON name PLUGGEDIN_NAME_GETCOMMANDICON, PLG_ENUMERATECOMMANDS name PLUGGEDIN_NAME_ENUMERATECOMMANDS; begin end.
| 固定リンク
type PLUGGEDIN_STRUCT = ^TPluggedin_struct; TPluggedin_struct = packed record (略) ps_pszFiles: PChar; ←ここが問題! (略) end;
struct _pluggedin_struct { (略) const char** ps_pszFiles; (略) };
type Tps_pszFiles = ^_Tps_pszFiles; _Tps_pszFiles = array[0..32767] of PChar; PLUGGEDIN_STRUCT = ^TPluggedin_struct; TPluggedin_struct = packed record ps_nPlugVersion: LongInt; ps_pszFunction: PChar; ps_execParallel: LongInt; ps_nFiles: LongInt; ps_pszFiles: Tps_pszFiles; ps_pnPageNumbers: LongInt; ps_pszExecFolder: PChar; ps_hwndDWDesk: LongInt; end;
function PLG_ExecuteCommand(pPlgStruct: PLUGGEDIN_STRUCT): LongInt; stdcall; (略) // 選択されたファイル名を順番に取得します。 for I := 0 to pPlgStruct^.ps_nFiles-1 do begin InputFile := pPlgStruct^.ps_pszFiles^[I]; (略) end;
| 固定リンク
| 固定リンク
#Rubyのコードです。 def myScript #四角形を作成 depth = 30.mm width = 60.mm model = Sketchup.active_model entities = model.active_entities pts = [] pts[0] = [0, 0, 0] pts[1] = [width, 0, 0] pts[2] = [width, depth, 0] pts[3] = [0, depth, 0] face = entities.add_face pts boundingbox = face.bounds endいろいろ調べてみると、Delphiで作成したDLLの手続き(関数)をRubyスクリプトから呼び出すサンプルがありました。 これを使うとDelphiで入力と計算を行い、その結果をRubyスクリプトで描画させるというスタイルが可能なようです。
| 固定リンク
| 固定リンク
library Project1; uses Windows, SysUtils; {$R *.res} const PLUGGEDIN_REGKEY = 'Software\\FujiXerox\\MPM3\\MPWS\\PLUGGEDIN'; MAX_PLUGGEDIN_NUMBER = 30; PLUGGEDIN_VERSION = 2; // PLUGGEDIN_NAME_INITIALIZE = '_PLG_Initialize@4'; PLUGGEDIN_NAME_FINALIZE ='_PLG_Finalize@4'; PLUGGEDIN_NAME_CANFINALIZE = '_PLG_CanFinalize@4'; PLUGGEDIN_NAME_REQUIREFILES = '_PLG_RequireFiles@4'; PLUGGEDIN_NAME_EXECUTECOMMAND = '_PLG_ExecuteCommand@4'; PLUGGEDIN_NAME_ISPARALLEL = '_PLG_IsParallel@4'; PLUGGEDIN_NAME_ISCLONINGCOMMAND = '_PLG_IsCloningCommand@4'; PLUGGEDIN_NAME_GETNEWCLONE = '_PLG_GetNewClone@8'; PLUGGEDIN_NAME_RELEASECLONE = '_PLG_ReleaseClone@4'; PLUGGEDIN_NAME_EXECUTABLE = '_PLG_Executable@8'; PLUGGEDIN_NAME_CANSETPROFILE = '_PLG_CanSetProfile@4'; PLUGGEDIN_NAME_SETPROFILE = '_PLG_SetProfile@4'; PLUGGEDIN_NAME_GETCOMMANDICON = '_PLG_GetCommandIcon@8'; PLUGGEDIN_NAME_ENUMERATECOMMANDS = '_PLG_EnumerateCommands@12'; type PLUGGEDIN_STRUCT = ^TPluggedin_struct; TPluggedin_struct = packed record ps_nPlugVersion: LongInt; ps_pszFunction: PChar; ps_execParallel: LongInt; ps_nFiles: LongInt; ps_pszFiles: PChar; ps_pnPageNumbers: LongInt; ps_pszExecFolder: PChar; ps_hwndDWDesk: LongInt; end; // Initialize Entry function PLG_Initialize(const cmdName: PChar): LongInt; stdcall; begin Result := 1; end; // Finalize Entry function PLG_Finalize(const cmdName: PChar): LongInt; stdcall; begin Result := 1; end; // CanFinalize Entry function PLG_CanFinalize(const cmdName: PChar): LongInt; stdcall; begin Result := 1; end; // RequireFiles Entry function PLG_RequireFiles(const cmdName: PChar): LongInt; stdcall; begin Result := 1; end; // ExecuteCommand Entry function PLG_ExecuteCommand(pPlgStruct: PLUGGEDIN_STRUCT): LongInt; stdcall; begin MessageBox(0, pPlgStruct.ps_pszFunction, 'Welcome to Docuworks Plugins', MB_OK); Result := 1; end; // IsParallel Entry function PLG_IsParallel(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // IsCloning Entry function PLG_IsCloningCommand(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // GetNewClone Entry function PLG_GetNewClone(cmdName: PChar; nBufSize: LongInt): LongInt; stdcall; begin Result := 0; end; // ReleaseClone Entry function PLG_ReleaseClone(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // Executable Entry function PLG_Executable(const cmdName: PChar; nArgFiles: LongInt): LongInt; stdcall; begin Result := 1; end; // CanSetProfile Entry function PLG_CanSetProfile(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // SetProfile Entry function PLG_SetProfile(const cmdName: PChar): LongInt; stdcall; begin Result := 0; end; // GetAppIcon Entry function PLG_GetCommandIcon(const cmdName: PChar; bNormalSize: LongInt): HICON; stdcall; begin Result := LoadIcon(hInstance, MAKEINTRESOURCE('MAINICON')); end; // EnumerateCommands Entry function PLG_EnumerateCommands(var cmdNameList: PChar; nBufSize: LongInt; var nBufSizeRequired: LongInt): LongInt; stdcall; const S = 'SamplePlugin by hiderin'; begin nBufSizeRequired := Length(S)+1; if (nBufSize < nBufSizeRequired) then begin Result := 0; Exit; end; StrCopy(@cmdNameList, S); Result := 1; end; exports PLG_INITIALIZE name PLUGGEDIN_NAME_INITIALIZE, PLG_FINALIZE name PLUGGEDIN_NAME_FINALIZE, PLG_CANFINALIZE name PLUGGEDIN_NAME_CANFINALIZE, PLG_REQUIREFILES name PLUGGEDIN_NAME_REQUIREFILES, PLG_EXECUTECOMMAND name PLUGGEDIN_NAME_EXECUTECOMMAND, PLG_ISPARALLEL name PLUGGEDIN_NAME_ISPARALLEL, PLG_ISCLONINGCOMMAND name PLUGGEDIN_NAME_ISCLONINGCOMMAND, PLG_GETNEWCLONE name PLUGGEDIN_NAME_GETNEWCLONE, PLG_RELEASECLONE name PLUGGEDIN_NAME_RELEASECLONE, PLG_EXECUTABLE name PLUGGEDIN_NAME_EXECUTABLE, PLG_CANSETPROFILE name PLUGGEDIN_NAME_CANSETPROFILE, PLG_SETPROFILE name PLUGGEDIN_NAME_SETPROFILE, PLG_GETCOMMANDICON name PLUGGEDIN_NAME_GETCOMMANDICON, PLG_ENUMERATECOMMANDS name PLUGGEDIN_NAME_ENUMERATECOMMANDS; begin end.
| 固定リンク
uses SHFolder; const // dwFlags用フラグ SHGFP_TYPE_CURRENT = 0; SHGFP_TYPE_DEFAULT = 1; procedure TForm1.Button1Click(Sender: TObject); var Path: String; begin SetLength(Path, MAX_PATH); if Succeeded(SHGetFolderPath(0, CSIDL_PERSONAL, 0, SHGFP_TYPE_CURRENT,PChar(Path))) then begin SetLength(Path, Pred(Pos(#0, Path))); ShowMessage(Path); end; end;
| 固定リンク
| 固定リンク
| 固定リンク
| 固定リンク
procedure TForm1.Button1Click(Sender: TObject); begin TOSTTSX1.Speak(Memo1.Text); end;これだけで、Memo1の内容を読み上げることができます。
| 固定リンク
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} const XDW_OPEN_UPDATE = 1; type XDW_DOCUMENT_HANDLE = record dummy: LongInt; end; XDW_OPEN_MODE = record nSize: Integer; nOption: Integer; end; XDW_DOCUMENT_INFO = record nSize: Integer; nPages: Integer; nVersion: Integer; nOriginalData: Integer; nDocType: Integer; nPermission: Integer; nShowAnnotations: Integer; nDocuments: Integer; nBinderColor: Integer; nBinderSize: Integer; end; function XDW_OpenDocumentHandle(const lpszFilePath: PAnsiChar; var Handle: XDW_DOCUMENT_HANDLE; var OpenMode: XDW_OPEN_MODE): Integer; stdcall; external 'xdwapi.dll'; function XDW_GetDocumentInformation(Handle: XDW_DOCUMENT_HANDLE; var DocumentInfo: XDW_DOCUMENT_INFO): Integer; stdcall; external 'xdwapi.dll'; function XDW_RotatePageAuto(Handle: XDW_DOCUMENT_HANDLE; nPage: Integer; reserved: Pointer=nil): Integer; stdcall; external 'xdwapi.dll'; function XDW_SaveDocument(Handle: XDW_DOCUMENT_HANDLE; reserved: Pointer= nil): Integer; stdcall; external 'xdwapi.dll'; function XDW_CloseDocumentHandle(Handle: XDW_DOCUMENT_HANDLE; reserved: Pointer=nil): Integer; stdcall; external 'xdwapi.dll'; function XDW_Finalize(reserved: Pointer = nil): Integer; stdcall; external 'xdwapi.dll'; procedure TForm1.Button1Click(Sender: TObject); var h: XDW_DOCUMENT_HANDLE; mode: XDW_OPEN_MODE; info: XDW_DOCUMENT_INFO; InputFile: String; I, J, K, Last_Page: Integer; begin // 文書ハンドルを開く mode.nSize := sizeof(XDW_OPEN_MODE); mode.nOption := XDW_OPEN_UPDATE; InputFile := 'c:\delphi.xdw'; I := XDW_OpenDocumentHandle(PAnsiChar(InputFile), h, mode); try if I > -1 then begin info.nSize := SizeOf(XDW_DOCUMENT_INFO); info.nPages := 0; info.nVersion := 0; info.nOriginalData := 0; info.nDocType := 0; info.nPermission := 0; info.nShowAnnotations := 0; info.nDocuments := 0; info.nBinderColor := 0; info.nBinderSize := 0; XDW_GetDocumentInformation(h, info); Last_Page := info.nPages; K := 0; for I := 1 to Last_Page do begin J := XDW_RotatePageAuto(h, I); K := K + J; end; // エラーがない場合に変更内容を保存する if K = 0 then XDW_SaveDocument(h); end; finally // 文書ハンドルを閉じる XDW_CloseDocumentHandle(h); end; end; procedure TForm1.FormDestroy(Sender: TObject); begin XDW_Finalize(nil); // XDW_RotatePageAutoを呼び出したらこの処理が必ず必要 end; end.
| 固定リンク
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls, ExtCtrls; type TForm1 = class(TForm) StringGrid1: TStringGrid; procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); procedure StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure StringGrid1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure StringGrid1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure StringGrid1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); procedure StringGrid1DragDrop(Sender, Source: TObject; X, Y: Integer); procedure FormCreate(Sender: TObject); private public end; var Form1: TForm1; implementation {$R *.dfm} const Flag = 1; var CurrRow, FocusRow: Integer; Sliding: Boolean; procedure TForm1.FormCreate(Sender: TObject); var I,J: Integer; begin StringGrid1.DefaultDrawing := False; StringGrid1.Align := alClient; StringGrid1.RowCount := 50; // とりあえずサンプルデータ for I := 1 to StringGrid1.RowCount -1 do for J := 1 to StringGrid1.ColCount -1 do StringGrid1.Cells[J,I] := 'ITEM'+IntToStr(I*J) ; end; procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); var DRect: TRect; Mode: Integer; begin DRect := Rect; InflateRect(DRect, -2, -2); { 描画位置の設定・・・適当に } if ACol = 1 then //右寄せ Mode := DT_RIGHT else if ACol = 2 then //左寄せ Mode := DT_LEFT else Mode := DT_CENTER; //中央 { 固定行が選択されている場合の表示 } if Integer(StringGrid1.Objects[ACol,ARow]) = Flag then begin StringGrid1.Canvas.Brush.Color := clGray; StringGrid1.Canvas.FillRect(Rect); DrawEdge(StringGrid1.Canvas.Handle, Rect, BDR_SUNKENINNER, BF_BOTTOMRIGHT); DrawEdge(StringGrid1.Canvas.Handle, Rect, BDR_SUNKENINNER, BF_TOPLEFT); DrawText(StringGrid1.Canvas.Handle, PChar(IntToStr(ARow)), Length(IntToStr(ARow)), DRect, Mode); Exit; end; { 固定行の標準描画 } if (ACol = 0) and (ARow > 0) then begin StringGrid1.Canvas.Brush.Color := clBtnFace; StringGrid1.Canvas.FillRect(Rect); DrawEdge(StringGrid1.Canvas.Handle, Rect,BDR_RAISEDINNER, BF_BOTTOMRIGHT); DrawEdge(StringGrid1.Canvas.Handle, Rect,BDR_RAISEDINNER, BF_TOPLEFT); DrawText(StringGrid1.Canvas.Handle, PChar(IntToStr(ARow)), Length(IntToStr(ARow)), DRect, DT_CENTER); Exit; end; { 固定列の標準描画 } if (ARow = 0) then begin StringGrid1.Canvas.Brush.Color := clBtnFace; StringGrid1.Canvas.FillRect(Rect); DrawEdge(StringGrid1.Canvas.Handle, Rect,BDR_RAISEDINNER, BF_BOTTOMRIGHT); DrawEdge(StringGrid1.Canvas.Handle, Rect,BDR_RAISEDINNER, BF_TOPLEFT); if (ACol > 0) then DrawText(StringGrid1.Canvas.Handle, PChar(IntToStr(ACol)), Length(IntToStr(ACol)), DRect, DT_CENTER); Exit; end; { 行選択、セル選択の背景色の設定 } if (goRowSelect in StringGrid1.Options) and (Integer(StringGrid1.Objects[0,ARow]) = Flag) then StringGrid1.Canvas.Brush.Color := clAqua else StringGrid1.Canvas.Brush.Color := clWindow; StringGrid1.Canvas.FillRect(Rect); DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol,ARow]), Length(StringGrid1.Cells[ACol,ARow]), DRect, Mode); if (not (goRowSelect in StringGrid1.Options)) and (gdFocused in State) then StringGrid1.Canvas.DrawFocusRect(Rect); end; procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FlagClear; var I: Integer; begin for I := 0 to StringGrid1.Cols[0].Count - 1 do StringGrid1.Cols[0].Objects[I] := nil; end; var I, ACol, ARow: Integer; begin if (Button = mbRight) then Exit; { マウスの座標から現在のセル位置を取得します。 } StringGrid1.MouseToCell(X, Y, ACol, ARow); if (ACol <= 0) and (ARow <= 0) then Exit; { 0列目をクリックされた場合の処理 } if (ACol = 0) then begin {0列で1行目以上の場合にはDragを許可します。} if StringGrid1.Objects[0,ARow] = TObject(Flag) then begin StringGrid1.Row := ARow; StringGrid1.BeginDrag(True); Exit; end; { 行選択の処理 } CurrRow := Arow; Sliding := True; StringGrid1.Options := StringGrid1.Options + [goRowSelect]; // CtrlキーかShiftキーが押されていない場合には、Flagを消去します。 if (not (ssCtrl in Shift)) and (not (ssShift in Shift)) then FlagClear; if (ssCtrl in Shift) then StringGrid1.Objects[0, ARow] := TObject(Flag) else if (ssShift in Shift) then begin FlagClear; // 選択範囲にFlagを設定します。 if (FocusRow < ARow) then begin for I := FocusRow to ARow do StringGrid1.Objects[0, I] := TObject(Flag); end else begin for I := FocusRow downto ARow do StringGrid1.Objects[0, I] := TObject(Flag); end end else StringGrid1.Objects[0,ARow] := TObject(Flag); { カーソルを現在の列に移動させます。 } StringGrid1.Row := ARow; FocusRow := ARow; StringGrid1.Invalidate; end else begin { 0列目以外の処理 } FlagClear; if ARow <> 0 then StringGrid1.Objects[0, ARow] := TObject(Flag); StringGrid1.Options := StringGrid1.Options - [goRowSelect]; FocusRow := ARow; end; end; procedure TForm1.StringGrid1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var ACol, ARow: Integer; begin {マウスの座標から現在のセル位置を取得します。} StringGrid1.MouseToCell(X, Y, ACol, ARow); if (ACol <= 0) and (ARow <= 0) then Exit; if Sliding and (ARow <> CurrRow)then begin if Integer(StringGrid1.Objects[0,ARow]) = Flag then StringGrid1.Objects[0,ARow] := nil else StringGrid1.Objects[0,ARow] := TObject(Flag); StringGrid1.Invalidate; CurrRow := Arow; end; end; procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Sliding := False; end; procedure TForm1.StringGrid1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); var ACol, ARow: Integer; begin if (Source is TStringGrid) then (Sender as TStringGrid).MouseToCell(X, Y, ACol, ARow); Accept := ((Sender is TStringGrid) and (Source is TStringGrid)) and ((Sender as TStringGrid) = (Source as TStringGrid)) and (ARow > 0); end; procedure TForm1.StringGrid1DragDrop(Sender, Source: TObject; X, Y: Integer); var I, DestRow, ACol: Integer; SL: TStringList; Temp: TList; begin Temp := TList.Create; try {挿入位置をマウス座標から取得します。} StringGrid1.MouseToCell(X, Y, ACol, DestRow); {DestRowまで選択行以外のものを保存します。} for I := 0 to DestRow -1 do begin if StringGrid1.Objects[0,I] <> TObject(Flag) then begin SL := TStringList.Create; SL.Assign(StringGrid1.Rows[I]); Temp.Add(SL); end; end; {選択行を保存します。} for I := 0 to StringGrid1.RowCount -1 do begin if StringGrid1.Objects[0,I] = TObject(Flag) then begin SL := TStringList.Create; SL.Assign(StringGrid1.Rows[I]); Temp.Add(SL); end; end; {DestRow以上で選択行以外を保存します。} for I := DestRow to StringGrid1.RowCount -1 do begin if StringGrid1.Objects[0,I] <> TObject(Flag) then begin SL := TStringList.Create; SL.Assign(StringGrid1.Rows[I]); Temp.Add(SL); end; end; {StringGrid1に設定します。} for I := 0 to Temp.Count -1 do StringGrid1.Rows[I].Assign(TStringList(Temp[I])); finally for I := 0 to Temp.Count -1 do TStringList(Temp[I]).Free; Temp.Free; end; end; end.
| 固定リンク
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OleCtrls, DESKCTRLLib_TLB; type TForm1 = class(TForm) DeskCtrl1: TDeskCtrl; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var WS: WideString; begin WS := 'C:\Delphi_QA_ja.xdw'; DeskCtrl1.LoadFile(WS); end; end.
| 固定リンク