【Delphi】IDE プラグイン『dNotes』を 10.4 Sydney 以降対応にする

# はじめに
以前スワンマン氏 (らいなタン氏) に作って頂き、とても重宝している **『dNotes』** を **10.4 Sydney** 以降で使えるようにするために、ちょっとだけ改変する事にしました。

 - [クズがプロジェクトマネージャ弄った結果。(Swanman's Horizon / 全力わはー)](https://lyna.hateblo.jp/entry/20150501/1430411992)
 - [自作プラグインの10.3 Rio対応状況。(Swanman's Horizon / 全力わはー)](https://lyna.hateblo.jp/entry/20181123/1542962830)

**10.3 Rio** 対応の `dNotes plugin Ver.0.0.7` をベースとします。

# dNotes とは
**『dNotes』** は、プロジェクトマネージャでファイルにコメントを入れられるようにする IDE プラグインです。~~Delphi 2010 以降に対応しています。~~ `CreateAnonymousThread()` を使っているため Delphi XE 以降の対応となりますが、少しの修正で Delphi 2010 で動作させる事ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/6181405e-955c-53c0-b6a7-857dd7db3078.png)

アフォみたいにファイルのあるプロジェクトではとても重宝します。

コメントを入れるには、ファイルを右クリックして [コメントの編集]  を選ぶか、マウスカーソルをコメントのカラム側に持っていった状態で〔F2〕を押します。コメント部分をマウスでクリックして編集モードにする事もできますが、コメントが入力されていない状態で編集モードにするのは難しいです (数 pixel しか許容しないので...)。

インストールの方法は **『dNotes』** 付属の readme.txt をご覧ください。

## 改変
大した変更ではありませんが、旧バージョン (2010～10.3 Rio) でコンパイルしても影響がないようにします。

### 改変点 #1

23 行目から始まる IDE の定義に **10.4 Sydney ～ 12 Athens** の分を追加します。**10.3 Rio** の定義もちょっと変更しておきます。

```pascal:UdNotes.pas

const
  {$IFDEF VER210}vclide = 'vclide140.bpl';{$ENDIF} // 2010
  {$IFDEF VER220}vclide = 'vclide150.bpl';{$ENDIF} // XE
  {$IFDEF VER230}vclide = 'vclide160.bpl';{$ENDIF} // XE2
  {$IFDEF VER240}vclide = 'vclide170.bpl';{$ENDIF} // XE3
  {$IFDEF VER250}vclide = 'vclide180.bpl';{$ENDIF} // XE4
  {$IFDEF VER260}vclide = 'vclide190.bpl';{$ENDIF} // XE5
  {$IFDEF VER270}vclide = 'vclide200.bpl';{$ENDIF} // XE6
  {$IFDEF VER280}vclide = 'vclide210.bpl';{$ENDIF} // XE7
  {$IFDEF VER290}vclide = 'vclide220.bpl';{$ENDIF} // XE8
  {$IFDEF VER300}vclide = 'vclide230.bpl';{$ENDIF} // 10 Seattle
  {$IFDEF VER310}vclide = 'vclide240.bpl';{$ENDIF} // 10.1 Berlin
  {$IFDEF VER320}vclide = 'vclide250.bpl';{$ENDIF} // 10.2 Tokyo
  {$IFDEF VER330}vclide = 'vclide260.bpl'; {$DEFINE NOHEADER} {$ENDIF} // 10.3 Rio    <-- 変更
  {$IFDEF VER340}vclide = 'vclide270.bpl'; {$DEFINE NOHEADER} {$ENDIF} // 10.4 Sydney <-- 追加
  {$IFDEF VER350}vclide = 'vclide280.bpl'; {$DEFINE NOHEADER} {$ENDIF} // 11 Alexandria <-- 追加
  {$IFDEF VER360}vclide = 'vclide290.bpl'; {$DEFINE NOHEADER} {$ENDIF} // 12 Athens <-- 追加
```

### 改変点 #2

957 行目から始まる Register() 手続きで、TreeView ヘッダのオプションに [hoVisible] を追加します。**10.3 Rio** 以降、プロジェクトマネージャの TreeView に**ヘッダが表示されなくなった**ため、カラムのリサイズもできなくなってしまったからです。

```pascal:UdNotes.pas

  objTree.EditDelay := 250;
  objHeader.Options := objHeader.Options - [hoAutoResize];
{$IFDEF NOHEADER}
  objHeader.Options := objHeader.Options + [hoVisible];
{$ENDIF}
  objTree.TreeOptions.SelectionOptions := objTree.TreeOptions.SelectionOptions + [toFullRowSelect, toExtendedFocus];

```
**・10.2 Tokyo**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/7767856e-8420-3e25-b516-76a698b45712.png)
**・10.4 Sydney**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/478bad5c-2f70-9782-be99-234a99acd00e.png)

### 改変点 #3

1022 行目から始まる Unregister() 手続きで、TreeView ヘッダのオプションから [hoVisible] を外します。これをやっておかないと、アンインストールした時に TreeView にヘッダが表示されたままになってしまいます。

```pascal:UdNotes.pas
{
        if (objColumns.Count < 2) or not (coVisible in objColumns[1].Options) then
          objHeader.Options := objHeader.Options + [hoAutoResize];
}
        if (objColumns.Count < 2) or not (coVisible in objColumns[1].Options) then
          begin
            objHeader.Options := objHeader.Options + [hoAutoResize];
          {$IFDEF NOHEADER}
            objHeader.Options := objHeader.Options - [hoVisible];
          {$ENDIF}
          end;
```


### 改変点 #4 (オプション)

**『dNotes』** は特定の拡張子のみコメントの編集を受け付けます。242 行目から始まる IsTargetExtension() 関数の中に対応させる拡張子を追加します。この改変では **uses** に (System.)StrUtils の追加が必要です。

```pascal:UdNotes.pas
uses
{$IFDEF USENAMESPACE}
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.StrUtils, System.Classes,
  System.Generics.Collections, System.Rtti, System.TypInfo, Vcl.Controls,
  Vcl.Forms, Vcl.Menus, Vcl.ActnList, ToolsAPI;
{$ELSE}
  Windows, Messages, SysUtils, StrUtils, Classes, Generics.Collections, Rtti, TypInfo,
  Controls, Forms, Menus, ActnList, ToolsAPI;
{$ENDIF}

...

function IsTargetExtension(const FileName: string): Boolean;
{
var
  ext: string;
begin
  ext := LowerCase(ExtractFileExt(FileName));
  Result := (ext = '.pas') or (ext = '.dfm') or (ext = '.fmx') or (ext = '.h')
    or (ext = '.hpp') or (ext = '.c') or (ext = '.cpp');
}
const
  pas_exts: array [0..3] of string = ('.pas', '.int', '.dfm', '.fmx');
  cpp_exts: array [0..3] of string = ('.h', '.hpp', '.c', '.cpp');
var
  ext: string;
begin
  ext := LowerCase(ExtractFileExt(FileName));
  Result := MatchText(ext, pas_exts) or MatchText(ext, cpp_exts);
end;
```

### 改変点 #5 (オプション)
マウスカーソルが [ファイル] / [コメント] のどちらのカラムにあってもコメントの編集を行えるようにするには、コンテキストメニューに何らかのショートカットを割り当てます。

次の例では〔F6〕でコメント編集ができるようになります。

```pascal:UdNotes.pas
function TProjectMenuCreatorNotifier.AddMenu(const Ident: string): TMenuItem;
begin
  Result := TMenuItem.Create(nil);
  if SameText(PreferredUILanguages, 'JA') then
    Result.Caption := sEditCommentJA
  else if SameText(PreferredUILanguages, 'DE') then
    Result.Caption := sEditCommentDE
  else
    Result.Caption := sEditCommentEN;
  Result.OnClick := MenuClick;
  Result.ShortCut := ShortCut(VK_F6, []); // <--- 追加
end;
```

# おわりに
**『dNotes』** はとても便利です！

::: note info
追記: 2021/09/11: 11 Alexandria に対応しました。
追記: 2023/11/16: 12 Athens に対応しました。
:::