オブジェクトツリーを印刷するには?

解決


桜坂  2007-03-01 14:10:19  No: 25125

オブジェクトツリーでオブジェクトが多い時、確認し、ソースを直すときに印刷できると便利ですが、オブジェクトツリーを印刷する方法は、どうするのでしょうか。
教えて下さい。


みんみん  2007-03-03 05:07:54  No: 25126

Delphiとは何の関係もない回答ですけど...
ふつうにスクリーンショットを撮ってそれを印刷してみたらどうですか?


桜坂  2007-03-03 15:17:58  No: 25127

みんみんさん、ありがとうございます。
私もフリーのスクリーンショットを使い印刷などをしていました。
しかし、オブジェクト数が100個以上になった場合、分割して何枚もスクリーンショットを撮ると、(繋ぎ合わせなど)さすがに大変です。
何か良い方法はないでしょうか。


TS  2007-03-03 18:20:12  No: 25128

自前でどうにかしないと出来ないと思います。
方法としては色々有るでしょうが
A案
  フォーム上で右クリック
  エデッタで表示
  全て選択状態にして
  Ctrl+C
  Excel上に貼り付け
  ソート
  objectが先頭にある行だけ残し削除
  編集->置き換えでobjectを空白に
B案
  フォーム上で右クリック
  エデッタで表示
  全て選択状態にして
  Ctrl+C
  何かのエデッタに貼り付け
  保存
  保存された物を自分でプログラムを使って
  好きに加工
C案
  他のプログラムから直接オブジェクトツリーのデータを取得
  加工(私には無理)


桜坂  2007-03-03 22:54:02  No: 25129

TSさん、ありがとうございます。
A案を試してみました。何とか、できそうです。
私の理想はC案ですが、色々なサイトを見ましたが見つかりませんでした。
十数年も違う言語で開発してくるとDelphi7でも同じような開発環境ができないか、と考えてしまいます。
前の言語では、プログラムを記述するソースの画面に、区画線を境にデータベースのフィールド(Delphiでいうオブジェクト)などを記述したソースを参照で表示でき、各々スクロールしてプログラムソース(又は反対にデータベースソース)を編集してきました。C案の様なツール(又はDelphiのテクニック)が有れば開発効率が上がると思ってお尋ねしました。


HOta  2007-03-03 23:24:19  No: 25130

Delphi7なら、別の編集ウィンドウを開けば参照できますよ。


桜坂  2007-03-04 00:35:46  No: 25131

えっ?別の編集ウインドウですか?
どのように別の編集ウインドウを開けて編集するのでしょうか。教えて下さい。
当方のオブジェクトツリーの状況は次の通りです。
Form
|  ---Default{Session}
|    --{Database1}
|      --<?>{Table1}  
|      --Constraints
|      --DataSetProvider1
|       --ClientDataSet1
|    FieldDefsなど・・・
|-PageControl1
|  --+ABC{TabSheet1}
|    1つのTabSheetに50くらいのオブジェクトがあります。
|     このオブジェクトを参照したいのです
|     全部で5つのTabSheetがあります。
|      TabSheetの下にはScrollBoxが各々あります。
よろしくお願いします。


HOta  2007-03-04 05:38:08  No: 25132

ソースの編集ウィンドウは編集ウィンドウ上で右クリックから「別の編集ウィンドウを開く」で編集ウィンドウをいくつでも開けます。


桜坂  2007-03-04 08:01:18  No: 25133

私の説明が悪かったかもしれません。
ソースの編集はできますが、その際、オブジェクトツリーのオブジェクトを参照したいのです。
オブジェクトツリーのオブジェクトを一覧できる方法を教えて頂ければ幸いです。
先に示しましたオブジェクトツリーには、約300個のオブジェクトがあり、NAMEなどを間違わないように記述するために参照できれば効率がよいと思っています。
よろしくお願いします。


HOta  2007-03-04 19:44:43  No: 25134

すみません。ソースを参照にだけ反応してしまいました。全体を読んでいませんでした。


桜坂  2007-03-05 18:14:20  No: 25135

皆さん、ありがとうございました。
とりあえず、TSさんのA案でやろうと思っています。
C案のようなツールが標準でDelphiに搭載されることを願っております。


NT系限定  2007-03-06 06:47:15  No: 25136

オブジェクトツリーのItemをMemoに。(Win9X系は実行不可)
未整形でチト見づらい?

type
  PInfo = ^TInfo;
  TInfo = packed record
    infoItem: TTVItem;
    infoText: array[0..255] of Char;
  end;
const
  MAXTEXTLEN = 50;
var
  hProcess : THandle;
  SysShared: PByte;
  sNode: string;
  Level: Integer;
  sDir: array[0..31]of string;
  hChild: HWND;

function GetItemByNameNT(Wnd: hWnd; hItem: HTREEITEM): HTREEITEM;
var
  info: TInfo;
  szBuffer: array [0..MAXTEXTLEN+1] of Char;
  hItemFound, hItemChild: HTREEITEM;
  BytesRW: Dword;
begin
  if (hItem = nil) then begin
    hItem := HTREEITEM(SendMessage(Wnd, TVM_GETNEXTITEM, TVGN_ROOT, 0));
    sNode := '';
    Level := 0;
  end;
  with Info do begin
    while (hItem <> nil) do begin
      infoItem.hItem := hItem;
      infoItem.mask := TVIF_TEXT or TVIF_CHILDREN;
      infoItem.pszText := PInfo(SysShared).infoText;
      infoItem.cchTextMax := MAXTEXTLEN;
      Win32Check(WriteProcessMemory(hProcess, SysShared, @Info, Sizeof(Info), BytesRW));
      SendMessage(Wnd, TVM_GETITEM, 0, LPARAM(SysShared));
      Win32Check(ReadProcessMemory(hProcess, SysShared, @Info, Sizeof(Info), BytesRW));

      if (infoItem.cChildren > 0) then begin
        if sNode = '' then begin
          sNode := infoText;
        end else begin
          sNode := sNode +' ⇒ '+ infoText;
        end;
        inc(Level); sDir[Level] := sNode;
        // 再帰コール
        hItemChild := HTREEITEM(SendMessage(Wnd, TVM_GETNEXTITEM, TVGN_CHILD, Longint(hItem)));
        GetItemByNameNT(Wnd, hItemChild);
      end else begin
        if sNode <> '' then Form1.Memo1.Lines.Add(sNode +' ⇒ '+ infoText);
      end;
      hItem := HTREEITEM(SendMessage(Wnd, TVM_GETNEXTITEM, TVGN_NEXT, LPARAM(hItem)));
    end;
    dec(Level);
    if Level > 0 then begin
      sNode  := sDir[Level];
    end else begin
      sNode := '';
    end;
  end;
  result := nil;
end;

function EnumChildFunc(hW: HWND; LParam: Pointer): BOOL; stdcall;
var
  szClassName: array[0..255]of Char;
begin
  if hW <> 0 then begin
    GetClassName(hW, szClassName, 255);
    if szClassName = 'TTreeView' then begin
      hChild := hW;
      Result := True;
    end;
  end else Result:= False;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  hItem : HTREEITEM;
  hw,hw2: HWND;
  pid: Integer;
begin
  Memo1.Clear;
  hChild := 0;
  hw := FindWindow('TObjectTreeView', nil);  // オブジェクトツリーのウィンドゥハンドル
  GetWindowThreadProcessId(hw, @pid);
  if (hw = 0)or(pid = 0) then exit;

  hProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  if (hProcess = 0) then RaiseLastWin32Error;
  SysShared := VirtualAllocEx(hProcess, nil, SizeOf(TInfo)+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  if Assigned(SysShared) then begin
    EnumChildWindows(hw, @EnumChildFunc, 0);
    hItem := GetItemByNameNT(hChild, nil);
    Win32Check(Boolean(VirtualFreeEx(hProcess, SysShared, 0, MEM_RELEASE)));
  end;
  CloseHandle(hProcess);
end;


桜坂  2007-03-06 17:43:44  No: 25137

うわぁ、すごい!
NT系限定さん、ありがとうございます。
しかし、初心者の私には、何がなんだか解読不能です。
Delphiの奥深さを痛感しました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加