Kamuycikap - SentenceDataBase

日々の勉強の記録を気分で書き綴るブログ

RaspberryPiのHDMIディスプレイ解像度を調整

自宅テレビの解像度を調整する

自宅テレビにHDMI接続して試してみると、視力検査のような小さな文字になってしまってます。
自宅のテレビは32型。
近くによると見えますが、気持ちとしては2mくらい離れて使いたい。
なので、解像度を調整します。

<目次>

  1. ディスプレイ設定のパラメータを確認
  2. /boot/config.txtの編集
  3. RaspberryPiの再起動

ディスプレイ設定のパラメータを確認

Google先生に聞いてみると、同じように調整している人たちの記録を閲覧することができます。
様々設定が記載されていましたが、下記の2点だけ決めればOKみたいです。

hdmi_group
hdmi_mode

config.txt設定詳細
ここを見て、自分がほしい解像度を選びます。
調査してみると、自分のテレビだとこのあたりでしっくりきました。

/boot/config.txtの編集

バックアップをとってからファイルを修正します

$ sudo cp /boot/config.txt /boot/config.txt.original
$ sudo vi /boot/config.txt

#でコメントアウトされているところを、#を消して有効にするだけです。

# uncomment to force a specific HDMI mode (this will force VGA)
hdmi_group=2   # <--- HDMI
hdmi_mode=23   # <--- 1280x768 60 Hz

RaspberryPiの再起動

コマンドで再起動!!

$ sudo shutdown -r now

もしも解像度指定に失敗したら・・・(´-ω-`;)ゞポリポリ

失敗したら、再起動と同時に画面が真っ暗!!になります。(*゚Д゚*)ェ…
その場合は・・

  1. SDカードを抜いてパソコンにセット!
  2. テキストエディタで、SDカードの/boot/config.txtを編集
  3. SDカードをRaspberryPiに戻して電源ON!

です。

優良アダルトサイト紹介の最終形態!!MaxInfo

Org-modeを8.2.10にしたら、Org-remember.elが使えなくなってた。

Org-capture

Org-modeでGTDな設定を行って自分の仕事を一元管理する仕組みを作って活用しようとアレコレしてました。
参考にしたのは下記のサイトです。

OrgMode/Org-modeでGTD実践(翻訳)

こちらのサイトをキッカケにしてOrg-modeのGTDについて調査していると、最新のOrg-modeが欲しくなり本家から最新のものを導入することにしました。
しかし、そこで思わぬ結果が。。。。

どうも、org-remenberはorg-captureというものに完全に置き換えられたみたいです。
※英語のマニュアルに書いてありました。
Org-mode Manual 8.2.10:9.1 Capture

org-capture-templatesを設定しなければならない

みたいですね。
書き方の参考になる情報を見つけました。
英語ですが、Google翻訳で頑張れば翻訳できそうです。
org-rememberテンプレートに似ていますね。

org-capture-templatesの設定要素について

設定要素「テンプレート」の書式

私の設定

Googleに「org-capture-templates」で質問すればアレコレと設定が出てきます。
以下に、私の設定を公開します。
ファイルパス部分については、自分の環境に合わせて読み替えてください。
アジェンダビューの設定についても説明は割愛します。

;; Org-captureをC-c rで呼び出す。
(define-key global-map "\C-cr" 'org-capture)

;; Org-caputure
;; Org-mode version8.xから導入されたorg-rememberの高機能版

(when (require 'org-capture nil t)

  (setq org-capture-templates
        '(("n" "Nico" entry (file+headline "~/.emacs.d/org_dat/gtd/nicosys.org" "INBOX")
           "* TODO %^{Brief Description} %^g\n%?\nAdded: %U")
          ("8" "870" entry (file+headline "~/.emacs.d/org_dat/gtd/870.org" "INBOX")
           "* TODO %^{Brief Description} %^g\n%?\nAdded: %U")
          ("h" "Home" entry (file+headline "~/.emacs.d/org_dat/gtd/home.org" "INBOX")
           "* TODO %^{Brief Description} %^g\n%?\nAdded: %U")
          ("p" "Projects" entry (file+headline "~/.emacs.d/org_dat/gtd/projects.org" "INBOX")
           "* TODO %^{Brief Description} %^g\n%?\nAdded: %U")
          ("d" "Note" entry (file+datetree "~/.emacs.d/org_dat/gtd/note.org" "MEMO")
           "* %^{Title} %^g\n%?\nAdded: %U")
          ))

  (setq org-agenda-custom-commands
        '(
          ("s" "SVF Lists" tags "SVF")           ; SVFタグを抽出
          ("p" "Projects Lists" tags "PROJECT")  ; PROJECTタグを抽出
          ("n" "Note Lists" tags "NOTE")         ; NOTEタグを抽出
          ("h" "Office and Home Lists"           ; @OFFICEタグでTODO
           ((agenda)
            (tags-todo "@OFFICE")
            (tags-todo "@HOME")))
          
          ("d" "Daily Action List"
           (
            (agenda "" ((org-agenda-ndays 1)
                        (org-agenda-sorting-strategy
                         (quote ((agenda time-up priority-down tag-up) )))
                        (org-deadline-warning-days 0)
                        )))))))



優良アダルトサイト紹介の最終形態!!MaxInfo

NTEmacs24にOrg-modeの最新安定版をインストールしたメモ

org-modeの最新版(8.2.10)インストール方法メモ

GTD(Getting Things Done)について勉強を初めて、さらにEmacsが好きになった私です。
Emacsには導入時にorg-modeがインストールされた状態になっていますが、本家サイトに最新版が公開されているのでそれを導入してみます。
org-remenberの設定も掲載していますが、これについては予めremember-modeの導入を終了させている必要があります。

.emacs.dやinit.elの説明は書いていません。
その辺りの知識を持っている人を前提としてメモします。

環境

今回はWindows7に導入したNTEmacs24への導入を行いますが、LinuxMacへの導入も基本的には同じ解釈でいけるのではないかと思っています。
おおまかな流れとしては、zipファイルをダウンロードして解凍し、load-pathの通っているディレクトリへコピーした後に、init.elに読み込み設定を書くだけです。
Linuxは動作しました、MacOSXは確認していません。

目次

  1. 最新ファイルのダウンロード
  2. ファイルの展開
  3. lispファイルのディレクトリをload-pathディレクトリ以下へコピー
  4. init.elへ設定

最新ファイルのダウンロード

以下の本家サイトから、最新安定版のzipファイルをダウンロードします。
org-mode本家

ブログ執筆時の最新ファイルは「org-8.2.10.zip」でした。

ファイルの展開

ダウンロードしたファイルを展開します。
すると、ドキュメント等を含めた一式のディレクトリが展開されます。
必要なのはlispディレクトリの中にあるファイル達です。

contrib <---- このディレクトリが必要
doc
etc
lisp  <---- このディレクトリが必要
mk
COPYING
Makefile
README
request-assign-future.txt

ディレクトリの意味などについては、READMEファイルをテキストエディタで閲覧すると書いてあります。

lispファイルのディレクトリをload-pathディレクトリ以下へコピー

展開したファイルに含まれている「lisp」ディレクトリをコピーします。
コピー先は、Emacsの設定ファイル「init.el」で設定されているであろう「load-path」が通っているディレクトリです。

おそらくですが、init.elに下記のような記述があると思います。

(setq load-path (cons “load-pathに含めたいディレクトリへのパス” load-path))

コピーしたら、どんな方法でもいいので「lisp」ディレクトリを「org」に名前変更します。
さらに、名前変更した「org」ディレクトリの中に、展開したzipファイルの中にある「contrib」ディレクトリをコピーします。

~/emacsのload-path/
   |
   |---org
      |
        |---contrib

これで、インストールは終了。
あとは、設定ファイルの記述です。

init.elへ設定

私の場合、init.elに以下のようにload-pathの設定をしています。
こうすることで、load-path以下にディレクトリを作ると自動的にload-pathに追加されていきます。
※このコードは、Emacs実践入門のサンプルソースを参照させて頂きました。

;; load-path を追加する関数を定義
(defun add-to-load-path (&rest paths)
  (let (path)
    (dolist (path paths paths)
      (let ((default-directory
              (expand-file-name (concat user-emacs-directory path))))
        (add-to-list 'load-path default-directory)
        (if (fboundp 'normal-top-level-add-subdirs-to-load-path)
            (normal-top-level-add-subdirs-to-load-path))))))

;; 引数のディレクトリとそのサブディレクトリをload-pathに追加
(add-to-load-path "elisp" "conf" "public_repos")

上記が良くわからない人は、こんなコードでもOKかなと思います。

(setq load-path (cons “~/path/to/orgdir/lisp” load-path))
(setq load-path (cons “~/path/to/orgdir/contrib/lisp” load-path))

org-modeの設定は、かなり好みがありますし、ネットには先人の設定が散らばっていますので好きなモノを採用すれば良いと思います。
以下、私の設定です。
ディレクトリパスの記載がありますが、そこは自分の環境に合わせて読み替えてください。

;; org-mode
(when (require 'org-install nil t)

  ;; 2015/02/03 GTDな管理を目指して過去のフォルダをコメントアウト。書き方のサンプルとして
  ;;(setq org-agenda-files (list "c:/work/documents/note/2014" "c:/work/documents/note/2015"))

  ;; There is Agenda files in Folder.
  (setq org-agenda-files (list "~/.emacs.d/org_dat/gtd"))
  
  ;; アジェンダに表示する時間を変更
  (setq org-agenda-time-grid
        '((daily today require-timed)
          "----------------"
          (900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400)))
  
  (define-key global-map "\C-cl" 'org-store-link)
  (define-key global-map "\C-ca" 'org-agenda)
  (define-key global-map "\C-cr" 'org-remember)

  ;; TODOの項目を増やす
  (setq org-todo-keywords
        '((sequence "TODO(t)" "APPT(a)" "|" "DONE(d)"))) ; TODO ← やっつける、APPT ← あとでやる、DONE ← 終了
  
  ;; (setq org-log-done 'time)  ; TODO→DONEで時間を記録する
  (setq org-log-done 'note)  ; TODO→DONEで時間を記録し、さらにノートの記載を促す

  ;; 経過時間の履歴保存
  (setq org-clock-persist 'istory)    ; 
  (org-clock-persistence-insinuate)   ;
  
  ;; 拡張子がorgのファイルを開いた時,自動的にorg-modeにする
  (add-to-list 'auto-mode-alist '("\\.org$" . org-mode))

  ;; org-modeでの強調表示を可能にする
  (add-hook 'org-mode-hook 'turn-on-font-lock)

  ;; エクスポートする時の設定
  (setq org-agenda-exporter-settings
        '((ps-number-of-columns 1)
          (ps-landscape-mode t)
          (htmlize-output-type 'css)))
  
  ;; 見出しの余分な*を消す
  (setq org-hide-leading-stars t))

再起動!!

Emacsを再起動して下記のコマンドを実施したとき、最新のバージョンになっていれば成功です。

M-x org-version 
Org-mode version 8.2.10


優良アダルトサイト紹介の最終形態!!MaxInfo

Windows8.1でTrinketを動かしてみた

Adafruit TrinketをWindows8.1で動かしてみた

大阪の日本橋にあるシリコンハウスのレジ横に掛けられていた1000円マイコン
AdafruitのTrinketを動かすまでの手順とメモ

  1. ArduinoIDEで開発が可能
  2. FDTIな仕組みがなくてもUSB接続だけでプログラムを転送できる
  3. カドが丸い超小型設計(100円玉くらい)
  4. 5V駆動(3Vバージョンも有り)

これが紹介されていた特徴です。
FDTIを購入して、ArduinoProとか購入を考えていたんですが・・・・
これは試してもいいかもと思いたって購入。

FDTIは一度購入すれば色々使い倒せるのですが、小型Arduinoを購入するとなるとArduinoProは高いです。
毎回2000円ほどの出費は辛い。
Atmega328Pにブートローダーとソフトを焼きこんでオリジナルで動かすと小さくはできますが、このTrinketはそれよりもさらに小さい。
使い倒せたら色々おもしろいかもです。
服に縫い付けても角丸なので引っかからないかな??とか思ったりします。

開発環境のダウンロード

本家のサイトに、開発環境の作り方が書いてあります。
ArduinoIDEに対応しているとはいえ、そのままソフトをコンパイルはできそうにありません。
まぁ、アーキテクチャが異なるので普通にはいかなくて当然ですね。

本家サイトを参考にしてアレコレ頑張ってもいいのですが、作業完了済みのArduinoIDEをダウンロードすることが出来ます。
こっちをダウンロードするほうが確実で速いですね。
中の仕組みは、暇な時に眺めればいいとして、Trinketを動かすことを優先とします。

https://learn.adafruit.com/introducing-trinket/setting-up-with-arduino-ide#the-fast-way

USBTinyドライバーのダウンロード

★ダウンロードはこちら★
https://learn.adafruit.com/usbtinyisp/drivers

今回はWindows8.1で利用することを想定しているので、Windows8.1バージョンをダウンロードします。
適当なフォルダに解凍しておきます。
※解凍するとInstall...とかそれらしい実行ファイルがありますがそれは実行しません。解凍するだけです。

USBTinyドライバーのインストール

ここのくだりでかなり悩みました。
ちなみに、私のパソコンは「Lenovo G-500」です。

本家サイトでは、TrinketをUSBコネクタ(タイプA <--> ミニB)をパソコン本体に接続すると、ドライバーインストールのダイアログが表示されるような事が書かれてたんですが、、、、私の場合はそれが出てきませんでした。
色々試した結果ですが

だったのでUSBハブを試してみると

USB2.0のハブ(電源供給)を経由して接続するとOK!!

という結果になりました。
Trinketが壊れてるのかとアレコレ考えましたが、どうも電流値が足りてなかったかもしれないですね。
ただ、海外ではハブを経由したらダメだったとか、直接接続してもイケたとか情報が散らばってます。
何が正しいのかはわかりませんが、色々ためさなければならないかもしれません。
※パソコン(無印デスクトップ)変えたらハブを経由しなくてもイケました。

ダイアログで、解凍したUSBTinyフォルダのトップフォルダを指定してあげると、自動的に適切なファイルを実行してドライバーのインストールが完了します。

開発環境の設定

無事に開発環境とドライバーのセットアップができたら、次は開発環境の設定。
難しいことはなく、マウスで特定の箇所を選択するだけ。

  1. ツールマイコンボード>Adafruit Trinket 16MHz
  2. ツール>書込装置>USBtinyISP

これだけ。

プログラムの準備

本家サイトに、Blinkのサンプルがあったのでそれをそのままコピペ。

      /*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.

  To upload to your Gemma or Trinket:
  1) Select the proper board from the Tools->Board Menu
  2) Select USBtinyISP from the Tools->Programmer
  3) Plug in the Gemma/Trinket, make sure you see the green LED lit
  4) For windows, install the USBtiny drivers
  5) Press the button on the Gemma/Trinket - verify you see
     the red LED pulse. This means it is ready to receive data
  6) Click the upload button above within 10 seconds
*/
 
int led = 1; // blink 'digital' pin 1 - AKA the built in red LED

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);

}

// the loop routine runs over and over again forever:
void loop() {
    digitalWrite(led, HIGH); 
    delay(1000);
    digitalWrite(led, LOW);
    delay(1000);
}

コンパイルしてみると無事に終了。

プログラムの転送

これも、ちょっと悩みました。
Trinketはシリアルで書き込むタイプではありません。
なので、根本的にUNOとかとは違います。

「ファイル」→「書き込み装置を使って書き込む」

を実行することでプログラムが転送されます。
ただし、注意が必要!!!

サンプルプログラムの冒頭に書かれている英文がヒントなのですが

  5) Press the button on the Gemma/Trinket - verify you see
     the red LED pulse. This means it is ready to receive data
  6) Click the upload button above within 10 seconds
(*´∀`)ノ 赤色LEDが点滅している10秒の間に書き込み動作をしてね!!

と言うことらしいです。
USBポートに接続すると、緑色のLEDが点灯し、追って赤色のLEDが点滅し始めます。
赤色LEDが点滅している時にプログラムを転送しないと、Trinketは受け付けてくれないようです。

(*´∀`)ノ タイミングを逃したらTrinketのResetボタンを押して仕切り直し

です。

無事にプログラムが書き込まれると、赤色LEDが1秒間隔で点滅します。


優良アダルトサイト紹介の最終形態!!MaxInfo

かなり昔のSkypeのチャットログを簡単に検索したいなぁ。

Skypeの過去ログを効果的に検索したい

こんな要望が最近頻発します。
遠く離れた方々と仕事をするときに、Skypeって結構有益なツールになり得るというか、かなり活用しています。

あれ・・・あれってどうだったっけ???

とか

あの話はこうだったはずだよね???

とか、うろ覚えだったり議事録が不足していたりした場合に過去ログを調査してみたいんですが、半年とか前の話になってくると、Skypeの機能では役不足

んで、ちょっと調べてみたら良いツールが有りました。

SkyHistory

このツール使うとあっという間に履歴を検索してくれます。
SkypeAPIを使って履歴を取り込むようなので、違うPCで発信したやりとりとかも検索することが出来ます。
Windowsなアプリです。

ここからダウンロード
    ↓
http://scand.com/products/skyhistory/install.html

便利なアプリをありがとう!!


優良アダルトサイト紹介の最終形態!!MaxInfo

WebBrowserコントロールで飛び先のURLを取得できない

WebBrowserを拡張してみました

環境はVisuasStudio2010です。

WebBrowserコントロールを使って、Webサイトのタグをたどってリンクを踏むプログラムを書いていました。

「新規ウィンドウを開くタイプのリンク」を踏んだ時の飛び先URL

これを取得するためにWebBrowserコントロールの「NewWindow」イベントを利用しようとしました。
URLの情報があるだろうと思っていたら、、、、取得できないんですね。

Google先生に聞いてみると、同じ様に飛び先のURLを取得するために試行錯誤している人が沢山いらっしゃいます。

行き着く先は、マイクロソフトのサポートページだったわけですが、なぜか現在はそのページを開くことが出来ません。
※リンク切れになっています。

そこで、参考サイトを参考にして、WebBrowserを継承した拡張コントロールを作ってみました。

プロジェクトの新規作成で「クラスライブラリ」を作成。 <- 名前:ExtendedWebBrowser.cs
プロジェクト名を「ExtWebBrowser」としました。

ソースコードはこんな感じです。
ExtendedNewWindowイベントとExtendedNavigatingイベントが追加されています。
それ以外は標準のWebBrowserコントロールと一緒です。

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ExtWebBrowser
{
    public class WebBrowserExtendedNavigatingEventArgs : CancelEventArgs
    {
        private string _Url;
        public string Url
        {
            get { return _Url; }
        }

        private string _Frame;
        public string Frame
        {
            get { return _Frame; }
        }

        public WebBrowserExtendedNavigatingEventArgs(string url, string frame)
            : base()
        {
            _Url = url;
            _Frame = frame;
        }
    }

    public class ExtendedWebBrowser : WebBrowser
    {
        AxHost.ConnectionPointCookie cookie;
        WebBrowserExtendedEvents events;

        protected override void CreateSink()
        {
            base.CreateSink();
            events = new WebBrowserExtendedEvents(this);
            cookie = new AxHost.ConnectionPointCookie(this.ActiveXInstance, events, typeof(DWebBrowserEvents2));
        }

        protected override void DetachSink()
        {
            if (null != cookie)
            {
                cookie.Disconnect();
                cookie = null;
            }
            base.DetachSink();
        }

        public event EventHandler<WebBrowserExtendedNavigatingEventArgs> ExtendedNavigating;
        public event EventHandler<WebBrowserExtendedNavigatingEventArgs> ExtendedNewWindow;

        protected void OnExtendedNavigating(string url, string frame, out bool cancel)
        {
            EventHandler<WebBrowserExtendedNavigatingEventArgs> h = ExtendedNavigating;
            WebBrowserExtendedNavigatingEventArgs args = new WebBrowserExtendedNavigatingEventArgs(url, frame);
            if (null != h)
            {
                h(this, args);
            }
            cancel = args.Cancel;
        }

        protected void OnExtendedNewWindow(string url, out bool cancel)
        {
            EventHandler<WebBrowserExtendedNavigatingEventArgs> h = ExtendedNewWindow;
            WebBrowserExtendedNavigatingEventArgs args = new WebBrowserExtendedNavigatingEventArgs(url, null);
            if (null != h)
            {
                h(this, args);
            }
            cancel = args.Cancel;
        }

        class WebBrowserExtendedEvents : StandardOleMarshalObject, DWebBrowserEvents2
        {
            ExtendedWebBrowser _Browser;
            public WebBrowserExtendedEvents(ExtendedWebBrowser browser)
            { _Browser = browser; }

            public void BeforeNavigate2(object pDisp, ref object URL, ref object flags, ref object targetFrameName, ref object postData, ref object headers, ref bool cancel)
            {
                _Browser.OnExtendedNavigating((string)URL, (string)targetFrameName, out cancel);
            }

            public void NewWindow3(object pDisp, ref bool cancel, ref object flags, ref object URLContext, ref object URL)
            {
                _Browser.OnExtendedNewWindow((string)URL, out cancel);
            }
        }

        [ComImport(), Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"),
         InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch),
         TypeLibType(TypeLibTypeFlags.FHidden)]
        public interface DWebBrowserEvents2
        {
            [DispId(250)]
            void BeforeNavigate2([In, MarshalAs(UnmanagedType.IDispatch)] object pDisp,
                 [In] ref object URL, [In] ref object flags,
                 [In] ref object targetFrameName, [In] ref object postData,
                 [In] ref object headers, [In, Out] ref bool cancel);
            [DispId(273)]
            void NewWindow3(
                [In,
                MarshalAs(UnmanagedType.IDispatch)] object pDisp,
                [In, Out] ref bool cancel,
                [In] ref object flags,
                [In] ref object URLContext,
                [In] ref object URL);
        }
    }
}

利用方法

このプロジェクトをビルドして保存します。
以上です。

作ったコントロールを使いたいときは、ExtWebBrowserプロジェクトを利用したいソリューションに追加して使います。
すると、ツールボックスに自動的に「ExtendedWebBrowser」が追加されています。
※アイコンが歯車

WebBrowserコントロールと同じ様に、D&DでFormに貼り付けられます。

ExtendedNewWindowイベント

これを利用します。
新規ウィンドウを作るタイプのリンクを踏むと、このイベントが呼ばれます。

private void extendedWebBrowser_ExtendedNewWindow(object sender, ExtWebBrowser.WebBrowserExtendedNavigatingEventArgs e)


       /// <summary>
        /// 拡張Webbrowserコントロール:Webページ新規ウィンドウで開くイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void extendedWebBrowser_ExtendedNewWindow(object sender, ExtWebBrowser.WebBrowserExtendedNavigatingEventArgs e)
        {
            var url = e.Url; // 飛び先のURLを取得できる
        }

上記の例にある引数「e」のUrlプロパティを参照すると、飛び先のURLが入っています。

プロジェクトを追加するのではなくDLLを参照して使いたい時

  1. コントロールを追加したいソリューションを開く
  2. ソリューション直下のフォルダにExtWebBrowserプロジェクトのbinフォルダの中にあるExtWebBrowser.dllをコピー
  3. ツールボックスのコントロールを右クリック → アイテムの選択 → .NET Frameworkコンポーネント → 参照
  4. ソリューション直下のフォルダにコピーしたExtWebBrowser.dllを指定

すると、ツールボックスにExtendedWebBrowserコントロールが追加されます。



優良アダルトサイト紹介の最終形態!!MaxInfo

C#でファイルをWebからダウンロード

PDFファイルをWebからダウンロードしてみる

というのを試してみました。
このサンプルを動かすためには、VisualStudioのツールボックスに.NETコントロールの「WebClientコントロール」を追加しとかなきゃいけません。

前回のブログで書いたやつですね。

自分のメモ的に残しておきます。
これは、非同期ダウンロードのサンプルです。

<<メソッドメモ>>
DownloadStartButton => WindowsFormに適当に配置されたボタン
DownloadCancelButton => WindowsFormに適当に配置されたボタン

PdfDownloadProgressChanged => WebClientコントロールのイベント「DownloadProgressChanged」に紐付けられています
PdfDownloadFileCompleted => WEbClientコントロールのイベント 「DownloadFileCompleted」に紐付けられています
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DownloadPDF
{
    public partial class MainForm : Form
    {

        public MainForm()
        {
            InitializeComponent();

            DownloadStartButton.Enabled = true;
            DownloadCancelButton.Enabled = false;
        }


        /// <summary>
        /// ダウンロードスタート(非同期)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DownloadStartButton_Click(object sender, EventArgs e)
        {
            DownloadStartButton.Enabled = false;
            DownloadCancelButton.Enabled = true;

            string fileName = @"C:\work\develop\C#\DownloadPDF\DownloadPDF\bin\Debug\hoge.pdf";         // 保存PDFファイル名
            Uri downloadURL = new Uri("http://www.eidos.ic.i.u-tokyo.ac.jp/~tau/lecture/computational_physics/docs/python-doc-2.7ja1-pdf/tutorial.pdf");                                                    // ダウンロードするPDFファイルのURL

            Console.WriteLine(downloadURL.AbsoluteUri);

            PdfDownloadwebClient.DownloadFileAsync(downloadURL,fileName);                               // 非同期ダウンロード開始



        }

        /// <summary>
        /// ダウンロードキャンセル処理(非同期)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DownloadCancelButton_Click(object sender, EventArgs e)
        {
            if (PdfDownloadwebClient != null)
            {
                PdfDownloadwebClient.CancelAsync();
            }
        }

        /// <summary>
        /// ダウンロード経過表示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PdfDownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e)
        {
            // ここでプログレスバー的なモノを表示できる。
            Console.WriteLine("{0}% ({1}byte 中 {2}byte) ダウンロードが終了しました。",
            e.ProgressPercentage, e.TotalBytesToReceive, e.BytesReceived);
        }

        /// <summary>
        /// ダウンロード完了通知処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PdfDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                MessageBox.Show("ダウンロードがキャンセルされました", "報告", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            }
            else if(e.Error != null)
            {
                MessageBox.Show("ダウンロードに失敗しました", "報告", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
            else
            {
                MessageBox.Show("ダウンロードを完了しました","報告",MessageBoxButtons.OK,MessageBoxIcon.Information,MessageBoxDefaultButton.Button1);
            }

            DownloadStartButton.Enabled = true;
            DownloadCancelButton.Enabled = false;
        }

    }
}



優良アダルトサイト紹介の最終形態!!MaxInfo