ごまなつ Blog

楽しく働ける世界を目指して

【Windows10】クリップボードの履歴機能が存在する

Windows10では、標準でクリップボードの履歴機能が搭載されています。クリップボードとは、コピーまたは切り取りした内容です。貼り付けできるものですね。クリップボードに何か存在する状態で新たにコピーまたは貼り付けをすると、最新のものしか貼り付けできません。ですが、Windowsロゴキー+vでクリップボードの履歴を表示できます。初回だけ、クリップボードの履歴機能を有効にする必要があります。 Windowsロゴキー+vを押すと以下の画面が表示されます。

開いた画面で、入力したい内容をダブルクリックまたはカーソルキーで選択&Enterで入力されます。

何が便利なのか

意外と、少し前のクリップボードの内容を使いたくなることがあります。その時に再びコピーしなくてもよいのは楽だと思います。

【キーボード】ローマ字テーブルを変更する

ローマ字テーブルは変更できます。「くぁ」を入力するために必ず「qa」を打たなくてもよいのです。

変更方法

IMEの設定を開きます。時計の左のIMEのアイコン(「あ」とか「A」とか書いてある)をクリックして、プロパティをクリックします。詳細設定をクリックし、全般タブのローマ字設定の変更をクリックします。変更したいものをダブルクリックか、項目操作の「追加」、「変更」、「削除」で変更できます。

どう活用するのか

キー入力では、ブラインドタッチをしている場合同じ指で連続入力することがあります。これは、異なる指が動く場合に比べて遅いですし、単純に打ちにくいです。そのため、何か一つのキーに割り当てると楽になります。例えば私は、「ざ」に対して「q」を割り当てています。この設定は、ひらがな一文字に対してでなくても設定できます。例えば私は、「する」に対して「sr」を割り当てています。このように、自分が扱いやすいように設定を変更できるのです。

注意点

もともと設定されているテーブルを変更するのはあまりお勧めしません。かなり自信がある人は行ってください。設定漏れを起こしたり、他環境に移行した時に困ります。

【Hugo】 Academic Themeを使ってポートフォリオを作ってみた

Hugoを使って、簡単に自己紹介ページを作ることができました。Hugoは、goで実装されている、静的サイトジェネレータです。

こちらが作成したサイトです。

gomana2.dev

静的サイトとは?

静的サイトとは、形が決まっている静的アセットを事前に配置しておき、ユーザのリクエストに対してホスティング先のWebサーバが事前配置された静的アセットを返すものです。サイトの表示スピードが速いですが、コンテンツの追加には時間がかかります。しかし、データベースを使用しないため低コスト・運用・メンテナンスフリーです。

静的サイトジェネレータとは?

配信可能な性的アセットを事前生成するツールです。近年では、gitとの連携によりコマンド一つで自動的に配信可能な静的アセットを自動的に生成し、サイト公開まで行うことができます。

Hugoの魅力

  • 生成時間が短い プレビューがストレスなくできます。また、ホスティングサービスの無料枠から外れる条件にビルド時間があることがあります。
  • 学習コストが低い Hugo特有のテンプレートと、HTML・CSSJavaScriptの基本を理解しているだけで使えます。
  • 開発が活発である 開発・メンテナンスがされなくなる心配は当分ないと考えられます。

Hugoのインストール・自作サイト公開まで

Git環境とGitHubアカウントとリポジトリを準備します。そして、Hugoをインストールします。サイトを構築するには、

hugo new site newsite

とすると、newsiteというディレクトリにサイトが構成されます。次に、テーマを設定します。テーマを設定していないと、サイトを構築することができません。HugoのテーマはHugo Themesにたくさんあるので気に入ったものを選びます。newsiteの中のthemeに、ダウンロードしたテーマを配置します。テーマはgit submoduleとなっています。私は動きが理解できなかったので、themeの中にcloneした後.gitを消去しました。

プレビューするには、

hugo server -D

とすると、http://localhost:1313にサイトが立ち上がります。選んだテーマによって、エラーが起こることがあります。その場合は、Hugo-extendedをインストールしてください。私は、Scoopを使ってインストールしました。

サイトの公開

今回はNetlifyを用います。 Netlifyの管理画面で「New site from Git」をクリックします。ガイダンスに従い、GitHubを選択します。デプロイするリポジトリを鰓時、Deploy siteをクリックします。ビルドが成功すれば「Preview deploy」から自分のサイトを確認できます。

利用するテーマによっては、Hugoのバージョンの関係でビルド失敗することがあります。その場合は、Setting>Build&deploy>Environmentに、KeyにHUGO_VERSION、Valueにバージョン番号を入力してSaveをクリックして下さい。

Academic Theme

https://themes.gohugo.io/academic/themes.gohugo.io

Academicというだけあり、大学教授向けのポートフォリオのテンプレートです。論文や執筆の項目がありますが、使わない項目は簡単に非表示にできます。公式ドキュメントを読みながら作成すると、簡単に自分のポートフォリオが完成しました。 ExampleSiteというディレクトリにサイトの例があるので、実際のサイトの画面とファイルの内容を見比べながら作っていきました。私に必要だったのは自己紹介・経歴・活動・出版物だったのでそれ以外を非表示にしました。

感想

こんなに簡単にリッチなコンテンツの静的サイトが作成できることにびっくりしました。このような仕組みとテーマを開発された方に感謝します。

【C#】ダイアログを出した後フォーカスがSplitConteinerの境界線に当たる

結論

原因はよくわかっていないが、this.ProcessTabKey(true);を入れると治った

経緯

画面にSplitConteinerを使って2つのパネルを配置していました。境界線にもフォーカスが当たるので、TabStopをfalseに変更し、フォーカスが当たらないようにしました。しかし、ある操作の後ダイアログを出し、backgroundworkerを使った非同期処理を行った後、フォーカスが境界線に当たっていました。backgroundworkerを使った非同期処理でない場合は、フォーカスが境界線に当たることはありませんでした。

フォーカスが境界線に当たってしまうのなら、Tabキーを押してしまえばいいのでは?と考えthis.ProcessTabKey(true);をbackgroundworkerを使った非同期処理の最後に書くと、解決しました。しかし、Tabを押したにもかかわらずタブオーダーがひとつ前に当たってしまうことが謎です。

【C#】ListViewがNonClickableの状態で、カラムヘッダーを右クリックしても右クリックメニューが出る

ListViewは、ItemのSubtextが追加されるとカラムに分けられます。ヘッダー部分をNonClickableで表示し、ListViewにContextMenustripを設定していました。。

NonClickableでも右クリックメニューは出る

NonClickableですが、MouseClickイベントは発生しませんでした。しかし、右クリックするとContextMenustripが表示されます。その時、選択しているインデックスは-1になっています。

解決法

 private void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Point targetPoint = listView.PointToClient(Cursor.Position);
            var Item = listView.HitTest(targetPoint).Item;

            if (Item == null || !Item.Bounds.Contains(targetPoint))
            {
                e.Cancel = true;
            }
        }

ContextMenuStrip_Openingでe.Cancelすることで右クリックメニューの表示をキャンセルできます。今回の場合は、ディスプレイの左上端が(0, 0)なのでコントロールの左上端が(0, 0)に変換します。HitTestで、右クリックした座標の項目情報をListViewItemとして取得し、ListViewItemでない場合はNullか、座標を含んでいないのでキャンセルします。これで解決かと思われたのですが、なんと、下にスクロールすることでヘッダー部分の下にListViewItemが隠され、ヘッダー部分を右クリックするとその部分の隠されているアイテムが選択された右クリックメニューが表示されました。そこで、

 private void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Point targetPoint = listView.PointToClient(Cursor.Position);
            var Item = listView.HitTest(targetPoint).Item;

            if (Item == null || !Item.Bounds.Contains(targetPoint) || listView.FocusedItem != Item)
            {
                e.Cancel = true;
            }
        }

として解決を図りました。選択されているItemがHitTestで取得したItemと異なった場合にキャンセルするようにしました。が、隠されているアイテムが選択されている状態だと、右クリックメニューが表示されました。もっと考えた結果、シンプルな方法がありました。

listView.TopItem()を使う

listView.topItemは表示されているItemの一番上のItemを取得します。よって、listView.topItemが、クリックした位置よりも上だったらキャンセルするようにします。

Point targetPoint = ChannelMaplistView.PointToClient(Cursor.Position);
 Point targetPoint = listView.PointToClient(Cursor.Position);
            var Item = listView.HitTest(targetPoint).Item;

            if (Item == null || !Item.Bounds.Contains(targetPoint) || listView.FocusedItem != Item)
            {
                e.Cancel = true;
     return;
            }
            if(ChannelMaplistView.TopItem.Position.Y > targetPoint.Y)
            {
                e.Cancel = true;
            }

座標は左上端が(0, 0)で、下が正の値になります。よって、クリックした位置より上ということは、TopItemのY座標がクリックした位置の座標よりも大きいことになります。この2つの条件を用いることで、うまくいきました。

【C#】ListViewのアイテム選択が外れる

ListViewを使っており、ContextMenustripを使っていました。選択されているItemが空白の場合と空白でない場合でContextMenustripの内容を変更していました。

アイテム選択が外れる場合

ListViewは、最終番号の下に空白が存在します。スクロールバーを表示するほどのアイテム数だったとしても、狭い範囲ですが空白が存在し、ここをクリックするとListViewのアイテムを何も選択しない状態になります。また、横にListViewを広げたときなど、アイテムの内容が存在しない部分をクリックしてもListViewのアイテムを何も選択しない状態になります。

MouseUpではイベントハンドラが発生するが、MouseClickでは発生しない

このアイテム選択が外れる領域では、クリックしてもListView.MouseClickは発生しません。しかし、MouseDown、MouseUpは発生します。今回の場合は、クリックした後のマウスの座標で処理したかったため、MouseUpを用います。

クリックした場所に一番近いアイテムを選択する

listView.InsertionMark.NearestIndex()では、指定したポイントに最も近い項目のインデックスを取得します。ポイントは、座標です。クリックした座標に最も近いListViewのインデックスを取得できるので、そこを選択状態にします。

private void listView_MouseUp(object sender, MouseEventArgs e)
        {
            // Retrieve the index of the item closest to the mouse pointer.
            int targetIndex = listView.InsertionMark.NearestIndex(new Point(e.X, e.Y));
            if (listView.SelectedItems.Count < 1)
            {
                listView.Items[targetIndex].Selected = true;
                listView.Items[targetIndex].Focused = true;
            }

こうすることで、下の空白をクリックすると最終番号が選択され、横の空白部分をクリックするとその場所に一番近いアイテムが選択されます。

座標系で注意すること

C#での座標系には以下の2種類があります。

  • ディスプレイの左上端が(0,0)
  • コントロールの左上端が(0,0)

使用しているライブラリがどちらの座標を用いているか確認しましょう。思っている座標とずれます。今回の場合は、コントロールの左上端が(0,0)なのでイベントハンドラが取得したクリックした座標をそのまま代入しています。ディスプレイの左上端が(0,0)の場合は、

Point targetPoint =  ListView.PointToClient(new Point(e.X, e.Y));

としてコントロールの左上端が(0,0)の座標に変換してください。

【outlook】定期的にメールを送信したい

業務の中で、同じ内容のメールを定期的に送信したいことがあると思います。そのようなときに、完全に自動とまではいきませんでしたが予定のアラームをクリックすることでメールを送信することができました。

参考サイト

https://docs.microsoft.com/ja-jp/outlook/troubleshoot/user-interface/create-recurring-emaildocs.microsoft.com

方法

outlookは、内部でvbsのマクロを走らせることができます。そこで、メール内容を入力した状態で送信フォームを開く、もしくは送信まで行うことができます。

メールを送信するフォームの作成

  1. まず、タブに開発を表示します。リボンの何もないところを右クリックして、リボンのユーザ設定を開きます。

右側のメインタブに、開発があるのでチェックを入れ、OKをクリックします。すると、メインタブに開発が表示されます。

  1. タスクを開き、[新しいタスク]をクリックします。

  2. タスク作成画面で[開発]の[このフォームのデザイン]をクリックし、コードの表示をクリックします。

  3. 開いたスクリプトエディター画面で、以下を入力します。宛先、CC、件名、本文は適宜変更してください。

Sub Item_PropertyChange(ByVal Name)    
    Select Case Name     
        Case "Status"
            if Item.Status = 2 then '2 = Completed
                Set NewItem = Application.CreateItem(0)
                NewItem.To = "宛先"
                NewItem.Cc =   "CC"
                NewItem.Recipients.ResolveAll
                NewItem.Subject = "件名"
                NewItem.Body = "本文"
                NewItem.Display
            End IF
        Case Else
    End Select
End Sub
  1. スクリプトエディターを閉じ、[フォーム]の[フォームの発行]をクリックします。

  2. [フォルダーの場所]で[タスク]をクリックし、[表示名][フォーム名]に好きな名前を入力して[発行]をクリックします。

  3. タスク作成画面を閉じます。変更は保存しません。

ここで作成したものは、[開発]の[フォームの選択]で選択することができ、上のコードが実行されます。その結果、設定した宛先、CC、件名、本文が入力されたメール送信画面が開きます。

定期的にするため予定のアラームと紐づける

  1. 先ほど作成したタスク作成画面を再び開きます。[開発]の[フォームの選択]か、[新しいアイテム]の[その他のアイテム]の[フォームの選択]で先ほど作成したタスクを開きます。
  2. タスクの件名、期限を設定します。[アラーム]チェックボックスをオンにします。また、定期的なアイテムをクリックし、アラームの頻度を設定し保存して閉じるをクリックします。 これで完成です。

実際の運用

タスクで設定した頻度で期限が来たらアラームが表示されます。そのアイテムを開き[進捗状況を完了にする]をクリックすると上のマクロが実行されて送信画面が開きます。 メール送信まで行いたい場合は、マクロのNewItem.Displayの後にNewItem.Sendを追加することでメール送信まで行うことができます。