none
コピーコンストラクタでCDCの実体をコピーしたい RRS feed

  • 質問

  • お世話になっております。VisualC++初心者です。

    今、Visual C++ 2010(MFC使用)で、CArrayにCDCの配列を持たせたいと考えているのですが、

    引数にCDCの実体を指定すると、ビルドエラーとなってしまいます。

    エラーの内容は、CObject定義のコピーコンストラクタや代入コンストラクタはprivateで宣言しているため、

    コピーも代入もできない、という内容でした。

    コピーコンストラクタや代入コンストラクタをオーバーライドし、その中でCDCの実体をコピー、代入するコードを

    書いてあげれば解決するかもしれない、というところまでは分かったのですが、

    CDCの場合、普通のオブジェクトのように=で代入できないため、

    どのように実体コピーすればよいのかわかりませんでした。

    色々検索してみたのですが、CDCを配列として持つということ自体、ほとんど情報がなかったため、

    もしかするとこういうことをやろうとする考え方自体が的外れなのでしょうか・・・。

    解決方法がわかる方がいらっしゃれば、ご教示のほど、お願いいたします。

    2013年5月20日 8:06

回答

  • まず、

     1.一般にCPaintDCなどは一時的なオブジェクトであるため、過去に保存したCDCを
      再利用することはできません。
      (但しCS_OWNDCクラススタイルのウインドウでのGetDC()で取得したHDCを除く)

     2.従って、一般にCDCを配列に保持して再利用することはしません。

    以上をご理解いただいたうえで、
    どのような経緯により、どの種類のCDCを配列化したCDCが必要になったのかを説明してみてはどうでしょう。



    2013年5月20日 9:21
  • CClientDCクラスは内部的にはWin32SDKのGetDC()を使ったキャッシュDCです。
    残念ながらキャッシュDCも一時的に使用できるだけで、保管して再利用することはできません。

    ただし、独自にCS_OWNDCスタイルを指定してRegisterClassEx()したウインドウクラス
    から作成したウインドウにおいては、HWNDの寿命の範囲内において、GetDC()で
    常に同一のHDCを取得できます。つまり常に有効となります。
    この場合は、WM_CREATE時などに一度取得したHDCはHWNDが破棄されるまで有効なままとなります。

    さて、Undo Redoですが、もちろん設計によりますが、一般に

     1.Undoは「直前の操作の取り消し」を意味すべき。であって、
      単に描画が元に戻れば良いというものではない。

    と、考えられます。従って、

     2.「直前の操作の取り消し」を行うと結果的に表示が以前の状態に戻る。

    という概念にすべきかもしれません。

    • 回答としてマーク arubi_momo 2013年5月21日 5:30
    2013年5月21日 0:55

すべての返信

  • まず、

     1.一般にCPaintDCなどは一時的なオブジェクトであるため、過去に保存したCDCを
      再利用することはできません。
      (但しCS_OWNDCクラススタイルのウインドウでのGetDC()で取得したHDCを除く)

     2.従って、一般にCDCを配列に保持して再利用することはしません。

    以上をご理解いただいたうえで、
    どのような経緯により、どの種類のCDCを配列化したCDCが必要になったのかを説明してみてはどうでしょう。



    2013年5月20日 9:21
  • 仲澤@失業者様

    ご返信ありがとうございます。

    やはりそうなんですね・・・検索しても情報がないので、

    一般的なやり方ではないのかなとは思ったのですが。

    現行システムにUndoRedo機能を実装する際に、

    保持しておかねばならないクラスの情報が多かったため、

    CDCの履歴を持てればそれが一番早いかと考えてしまいました。

    調べたところ、一般的な方法はクラス情報を保持して再描画、

    もしくはコマンドパターンの配列を使用する、ということのようですね。

    現行システムのつくりをもう一度確認したうえで、どの方法を使用するか

    再考したいと思います。

    勉強になりました。ありがとうございました。

    2013年5月21日 0:31
  • 仲澤@失業者様

    すみません、一点回答が漏れていました。

    ちなみに配列にしようとしたDCはCClientDCです。

    2013年5月21日 0:34
  • CClientDCクラスは内部的にはWin32SDKのGetDC()を使ったキャッシュDCです。
    残念ながらキャッシュDCも一時的に使用できるだけで、保管して再利用することはできません。

    ただし、独自にCS_OWNDCスタイルを指定してRegisterClassEx()したウインドウクラス
    から作成したウインドウにおいては、HWNDの寿命の範囲内において、GetDC()で
    常に同一のHDCを取得できます。つまり常に有効となります。
    この場合は、WM_CREATE時などに一度取得したHDCはHWNDが破棄されるまで有効なままとなります。

    さて、Undo Redoですが、もちろん設計によりますが、一般に

     1.Undoは「直前の操作の取り消し」を意味すべき。であって、
      単に描画が元に戻れば良いというものではない。

    と、考えられます。従って、

     2.「直前の操作の取り消し」を行うと結果的に表示が以前の状態に戻る。

    という概念にすべきかもしれません。

    • 回答としてマーク arubi_momo 2013年5月21日 5:30
    2013年5月21日 0:55
  • 仲澤@失業者様

    お世話になります。

    丁寧なご説明、ありがとうございます。

    確かに、Undoの概念として、描画が元に戻ればよいというのは違いますよね。

    その時クラスに保持されているデータと、絵に齟齬が生じるわけですものね。

    考えが足りませんでした。再考いたします。

    ありがとうございました。

    2013年5月21日 5:30