Quantcast
Channel: プログラム の個人的なメモ
Viewing all 860 articles
Browse latest View live

【C#】【Form】PictureBox [7] ~ 画像をコピーする・その2 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37857445.html
で、画像をクリップボードにコピーしたが、
Graphicsで描画した図形も含めてコピーはできない。

今回は、Graphicsで描画した図形も含めてコピーする方法について記載する。

■ 解決案

 * コピー直前の対象インスタンス(下記でいうと「selectedImage」)に対して、
   画面に描画している内容(下記でいう「this.DeawText()」の内部)を再度行う。

サンプル抜粋

https://blogs.yahoo.co.jp/dk521123/37857445.html
の「例2:矩形で囲ってリリースしたタイミングでコピー」がベース
    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
      if (this.targetRectangle.Height == 0 || this.targetRectangle.Width == 0)
      {
        return;
      }

      var pictureBox = sender as PictureBox;

      var start = this.startPoint;
      var end = e.Location;
      var copyArea = Rectangle.FromLTRB(
          Math.Min(start.X, end.X), Math.Min(start.Y, end.Y),
          Math.Max(start.X, end.X), Math.Max(start.Y, end.Y));
      using (var image = new Bitmap(pictureBox.Image))
      using (var selectedImage = image.Clone(copyArea, image.PixelFormat))
      using (var graphics = Graphics.FromImage(selectedImage))
      {
        // ★ここで描画する★
        this.DeawText(graphics);

        // 画像をクリップボードにコピー
        Clipboard.SetImage(selectedImage);
      }

      pictureBox.Invalidate();
      this.startPoint = Point.Empty;
      this.targetRectangle = Rectangle.Empty;
    }

    private void DeawText(Graphics g)
    {
      Font fnt = new Font("Arial", 20);

      g.RotateTransform(45);
      g.TranslateTransform(0, 0);
      g.DrawString("Hello World!!", fnt, Brushes.White, 100, 100);
    }

関連記事

PictureBox

PictureBox [1] ~ 画像を表示する ~
https://blogs.yahoo.co.jp/dk521123/23504075.html
PictureBox [2] ~ PictureBox を マウスで移動する ~
https://blogs.yahoo.co.jp/dk521123/37861699.html
PictureBox [3] ~ マウスホイール で画像の拡大・縮小する ~
https://blogs.yahoo.co.jp/dk521123/37866101.html
PictureBox [4] ~ PictureBox 内に文字列を描画する ~
https://blogs.yahoo.co.jp/dk521123/37890831.html
PictureBox [5] ~ PictureBox 内に画像を描画する ~
https://blogs.yahoo.co.jp/dk521123/37890873.html
PictureBox [6] ~ PictureBox 内でMouseMoveイベントにより線を描画する ~
https://blogs.yahoo.co.jp/dk521123/37905014.html
PictureBox [7] ~ 画像をコピーする・その1 ~
https://blogs.yahoo.co.jp/dk521123/37857445.html

その他

Windows Form ~ 目次 ~
https://blogs.yahoo.co.jp/dk521123/8054245.html
クリップボード
https://blogs.yahoo.co.jp/dk521123/7518189.html

【C#】【スレッド】BlockingCollection ~ Producer-Consumerパターン ~

【Windowsサービス】Windowsサービス ~ Hello World編 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/31706797.html
の頃は、無料版 Visual Studioでは簡単には作れなかったが
Visual Studio Community 2017 だと、簡単に作れそうなので、メモする。

■ 環境

 * Visual Studio Community 2017 (C#)
 * Windows 10

■ 手順

[1] Visual Studio を立ち上げて、[ファイル]-[新規作成]-[プロジェクト]を選択
[2] [Visual C#]-[Windows デスクトップ]-[Windowsサービス(.NET Framework)]を選択し、
    任意の名前、.NET Frameworkなどを入力・指定して「OK」ボタン押下
 => とりあえず、今回は、そのままで。


関連記事

Windowsサービス ~ 基本編 ~

https://blogs.yahoo.co.jp/dk521123/31702889.html

SCコマンド ~ サービスの制御 ~

https://blogs.yahoo.co.jp/dk521123/29631029.html

VS Express で Windowsサービス のテンプレート作成

https://blogs.yahoo.co.jp/dk521123/31706797.html

ServiceControllerクラス ~サービスをコントロールする~

https://blogs.yahoo.co.jp/dk521123/31737290.html

【C#】【Form】Windows アプリ⇔ ブラウザ 起動するには

$
0
0

■ Windows アプリからブラウザを起動するには

 * 『System.Diagnostics.Process.Start("【URL】")』を実行する

サンプル

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace SampleForm
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      Process.Start("https://blogs.yahoo.co.jp/dk521123/37951845.html");
    }
  }
}

参考文献

https://www.ipentec.com/document/csharp-windows-application-open-website

■ ブラウザからWindows アプリを起動するには

サンプル

<html>
<body>
<a href="helloworld:">Click Me!</a>
</body>
</html>

参考文献

http://ascii.jp/elem/000/001/211/1211206/
https://qiita.com/tukiyo3/items/40bff09692bfd0792a0f
https://garafu.blogspot.com/2014/02/url.html


■ おまけ:PC起動時にアプリケーションを自動で起動する

参考文献

https://www.indival.co.jp/2017/08/23/5223/

関連記事

Windows Form ~ 目次 ~

https://blogs.yahoo.co.jp/dk521123/8054245.html

【Windowsサービス】Windowsサービス ~ WCFでクライアント側と通信する ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37948659.html
で、簡単なWindowsサービスを作成できたので、
今度は、プロセス間通信(IPC:Inter Process Communication)を実現できる
WCF(Windows Communication Foundation)を使って、
以下の「構成」のような「Windowsサービス - 他のアプリ」とのやり取りをする

構成

サービス側
 * Windows Service (WindowsService1)
クライアント側
 * Windows Form (SampleForm)
  + button x 1
  + textBox x 2
  + label x 1

■ サンプル

前提条件

 * WCFを使うために「System.ServiceModel」を参照追加しておくこと
 * サービス側、クライアント側両方とも「管理者として実行」で実行されていること
  => Visual Studio で実行するなら、Visual Studioを「管理者として実行」で実行する

サービス側 (WindowsService1)

https://blogs.yahoo.co.jp/dk521123/37948659.html
をベースに
https://blogs.yahoo.co.jp/dk521123/31872515.html
のWCFの実装を組み込む。

 => 「installutil WindowsService1.exe」でWindowsサービスをインストールし、
    サービスとして開始させておく。
Service1.cs
using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceProcess;

namespace WindowsService1
{
  public partial class Service1 : ServiceBase
  {
    private ServiceHost host;

    public Service1()
    {
      InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
      Uri baseUri = new Uri(@"http://localhost:8888/SampleWcfService");
      try
      {
        this.host = new ServiceHost(typeof(SampleWcfService), baseUri);
        var binding = new BasicHttpBinding();
        this.host.AddServiceEndpoint(typeof(ISampleWcfService), binding, "Plus");
        this.host.Open();

        EventLog.WriteEntry(String.Format("{0} : Starting Windows Service...", DateTime.Now));
      }
      catch (Exception ex)
      {
        Console.Write(ex.Message);
      }
    }

    protected override void OnStop()
    {
      EventLog.WriteEntry(String.Format("{0} : Stopping Windows Service...", DateTime.Now));
      if (this.host != null)
      {
        this.host.Close();
      }
      EventLog.WriteEntry(String.Format("{0} : Done Windows Service...", DateTime.Now));
    }
  }

  [ServiceContract]
  public interface ISampleWcfService
  {
    [OperationContract]
    int Plus(int value1, int value2);
  }

  public class SampleWcfService : ISampleWcfService
  {
    public int Plus(int value1, int value2)
    {
      Trace.WriteLine("Called me?");
      return value1 + value2;
    }
  }
}

クライアント側 (SampleForm)

using System;
using System.ServiceModel;
using System.Windows.Forms;

namespace SampleForm
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      var endpointAddress = new EndpointAddress("http://localhost:8888/SampleWcfService/Plus");
      using (var channel = new ChannelFactory<ISampleWcfService>(new BasicHttpBinding()))
      {
        var service = channel.CreateChannel(endpointAddress);
        int value1 = Convert.ToInt32(this.textBox1.Text);
        int value2 = Convert.ToInt32(this.textBox2.Text);
        this.label1.Text = service.Plus(value1, value2).ToString();
        channel.Close();
      }
    }
  }

  [ServiceContract]
  public interface ISampleWcfService
  {
    [OperationContract]
    int Plus(int value1, int value2);
  }
}

動作確認

 * Formを起動しTextBoxに「31」「12」を入れて、ボタン押下すると、
   「43」と表示されるはず。

関連記事

Windowsサービス

Windowsサービス ~ 基礎知識編 ~
https://blogs.yahoo.co.jp/dk521123/31702889.html
Windowsサービス ~ Hello World編 ~
https://blogs.yahoo.co.jp/dk521123/37948659.html

WCF

WCF ~ 基礎知識編 ~
https://blogs.yahoo.co.jp/dk521123/22254537.html
WCF ~ Hello World編 ~
https://blogs.yahoo.co.jp/dk521123/31872515.html

【WCF】【C#】WCF ~ WCF に Javaクライアントでアクセスする ~

$
0
0

■ はじめに

 WCF で作成したサービスに、クライアントとして、
Javaでアクセスする必要がありそうなので、調べてみた。

なお、実装には、以下のサイトが役に立った。(特にJava側の実装で)
https://social.msdn.microsoft.com/Forums/en-US/f187404c-ba01-4832-a03e-f50ffadb8d26/c-wcf-service-and-java-client?forum=wcf

■ サンプル

前提条件

 * 「System.ServiceModel」を参照追加しておくこと
 * サービス側、クライアント側両方とも「管理者として実行」で実行されていること
  => Visual Studio で実行するなら、Visual Studioを「管理者として実行」で実行する

サービスの実装(C#)

 * プロジェクト「SampleForm」
Form1.cs
using System;
using System.ServiceModel;
using System.Windows.Forms;
using System.Diagnostics;

namespace SampleForm
{
  public partial class Form1 : Form
  {
    private ServiceHost host;

    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      Uri baseUri = new Uri(@"http://localhost:8888/SampleWcfService");

      try
      {
        this.host = new ServiceHost(typeof(SampleWcfService), baseUri);
        var binding = new WSHttpBinding();
        this.host.AddServiceEndpoint(typeof(ISampleWcfService), binding, "Plus");
        this.host.Open();
        this.label1.Text = "Start WCF service";
      }
      catch (Exception ex)
      {
        this.label1.Text = ex.Message;
      }
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
      if (this.host != null)
      {
        this.host.Close();
      }
    }
  }

  [ServiceContract]
  public interface ISampleWcfService
  {
    [OperationContract]
    int Plus(int value1, int value2);
  }

  public class SampleWcfService : ISampleWcfService
  {
    public int Plus(int value1, int value2)
    {
      Trace.WriteLine("Called me?");
      return value1 + value2;
    }
  }
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <!-- ★ 追加・ここから ★ -->
  <system.serviceModel>
        <services>
            <!-- 注意: サービス名は、サービスの実装の構成名と一致しなければなりません。 -->
            <service name="SampleForm.SampleWcfService" behaviorConfiguration="SampleWcfServiceBehaviors" >
                <!-- 次のエンドポイントを追加してください。  -->
                <!-- 注意: サービスには、このエンドポイントに追加する HTTP ベース アドレスがなければなりません。 -->
                <endpoint contract="SampleForm.ISampleWcfService" binding="mexHttpBinding" address="mex" />
            </service>
        </services>
 
        <behaviors>
            <serviceBehaviors>
                <behavior name="SampleWcfServiceBehaviors" >
                    <!-- 次の要素をサービス動作構成に追加してください。 -->
                    <serviceMetadata httpGetEnabled="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
  </system.serviceModel>
  <!-- ★ 追加・ここまで ★ -->
</configuration>

クライアントの実装(Java)



関連記事

WCF

WCF ~ 基礎知識編 ~
https://blogs.yahoo.co.jp/dk521123/22254537.html
WCF ~ Hello World編 ~
https://blogs.yahoo.co.jp/dk521123/31872515.html
WCF に Javaでアクセスした際のトラブルシューティング
https://blogs.yahoo.co.jp/dk521123/27253094.html

Java


https://blogs.yahoo.co.jp/dk521123/31944955.html

【トラブル】【WCF】WCF に Javaでアクセスした際のトラブルシューティング

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/37962361.html
を行った際に発生したトラブルシュートをまとめる

それ以外のWCF絡みのトラブルは以下の関連記事を参照のこと。
【トラブル】【WCF】WCFに関するトラブルシューティング
https://blogs.yahoo.co.jp/dk521123/31879191.html

■ 「このサービスのメタデータ公開は現在は無効になっています」が表示

WCFのエンドポイントにブラウザでアクセスしたら(以下の「現象発生例」を参照)、
ブラウザ上に以下の「エラー内容」が表示される

エラー内容

これは Windows© Communication Foundation サービスです。

このサービスのメタデータ公開は現在は無効になっています。

このサービスにアクセスできる場合は、次の手順に従って Web または
アプリケーションの構成ファイルを変更することにより、メタデータの公開を有効にできます。

現象発生例

 * 以下のサンプルに対して、
   ブラウザで「http://localhost:8888/SampleWcfService」にアクセスする
WCF ~ Hello World編 ~
https://blogs.yahoo.co.jp/dk521123/31872515.html

原因

 * サービスのメタデータ公開が無効になっているため(エラー内容そのままだが)

解決案

 * サービスのメタデータ公開が有効にする
  => ブラウザでの表示に結構詳しく書いてあるので、落ち着いて一読した方がいいかも
  => App.config を追加し、以下の内容を追記
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <!-- ★ 追加・ここから ★ -->
  <system.serviceModel>
    <services>
      <!-- 注意: サービス名は、サービスの実装の構成名と一致しなければなりません。 -->
      <service name="SampleForm.SampleWcfService" behaviorConfiguration="SampleWcfServiceBehaviors" >
        <!-- 次のエンドポイントを追加してください。  -->
        <!-- 注意: サービスには、このエンドポイントに追加する HTTP ベース アドレスがなければなりません。 -->
        <endpoint contract="SampleForm.ISampleWcfService"
                  name="DemoWcfService" binding="basicHttpBinding" address="Plus" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8888/SampleWcfService"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SampleWcfServiceBehaviors" >
          <!-- 次の要素をサービス動作構成に追加してください。 -->
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <!-- ★ 追加・ここまで ★ -->
</configuration>

■ 「コントラクト名 XXX は、サービス YYY によって実装されたコントラクトの一覧から見つかりませんでした。」が表示

上記の『「このサービスのメタデータ公開は現在は無効になっています」が表示』の対応で
WCFサービスを起動したら、以下の「エラー内容」の例外が発生した

エラー内容

コントラクト名 'SampleForm.SampleWcfService' は、
サービス 'SampleWcfService' によって実装されたコントラクトの一覧から見つかりませんでした。

原因

 * App.config のendpointタグのcontract属性が正しくなかった

解決案

 * App.config を修正
修正前
<endpoint contract="ISampleWcfService" binding="mexHttpBinding" address="mex" />
修正後
<endpoint contract="SampleForm.ISampleWcfService" binding="mexHttpBinding" address="mex" />

■ JavaクライアントでWSDLからコードジェネレートする際に「IWAB0399E」が発生

 Javaクライアント作成において
「http://localhost:8888/SampleWcfService?wsdl」を指定したら
以下の「エラー内容」が表示された

エラー内容

IWAB0399E Error in generating Java from WSDL:  java.io.IOException: 生成に失敗しました。WSDLドキュメント http://localhost:8888/SampleWcfService?wsdl=wsdl0 内に未定義のportType(ISampleWcfService)があります。 
ヒント: <binding type=".."> が十分に適したものか確認して下さい/ [en]-(Emitter failure.  There is an undefined portType (ISampleWcfService) in the WSDL document http://localhost:8888/SampleWcfService?wsdl=wsdl0.
Hint: make sure <binding type=".."> is fully qualified.)

    java.io.IOException: 生成に失敗しました。WSDLドキュメント http://localhost:8888/SampleWcfService?wsdl=wsdl0 内に未定義のportType(ISampleWcfService)があります。
    ヒント: <binding type=".."> が十分に適したものか確認して下さい/ [en]-(Emitter failure.  There is an undefined portType (ISampleWcfService) in the WSDL document http://localhost:8888/SampleWcfService?wsdl=wsdl0.
    Hint: make sure <binding type=".."> is fully qualified.)
    at org.apache.axis.wsdl.symbolTable.SymbolTable.checkForUndefined(SymbolTable.java:596)
    at org.apache.axis.wsdl.symbolTable.SymbolTable.populate(SymbolTable.java:715)
    at org.apache.axis.wsdl.symbolTable.SymbolTable.populate(SymbolTable.java:734)
    at org.apache.axis.wsdl.symbolTable.SymbolTable.add(SymbolTable.java:543)
    at org.apache.axis.wsdl.symbolTable.SymbolTable.populate(SymbolTable.java:518)
    at org.apache.axis.wsdl.symbolTable.SymbolTable.populate(SymbolTable.java:495)
    at org.apache.axis.wsdl.gen.Parser$WSDLRunnable.run(Parser.java:361)
    at java.lang.Thread.run(Thread.java:744)

解決案

「http://localhost:8888/SampleWcfService?wsdl」
ではなく
「http://localhost:8888/SampleWcfService?singleWsdl」
を指定する

関連記事

WCFに関するトラブルシューティング

https://blogs.yahoo.co.jp/dk521123/31879191.html

WCF ~ WCF に Javaクライアントでアクセスする ~

https://blogs.yahoo.co.jp/dk521123/37962361.html

【WCF】【C#】WCF ~ あれこれ編 ~

$
0
0

■ 一方向通信を実装するには...

 WCFサービスで、Producer-Consumer パターン(生産者-消費者パターン)
のようなことをやろうと調べていたら、意外と簡単にできそうなのでメモ
【デザインパターン】【非同期】Producer-Consumer パターン
https://blogs.yahoo.co.jp/dk521123/32914080.html
BlockingCollection ~ Producer-Consumerパターン ~
https://blogs.yahoo.co.jp/dk521123/37943991.html

解決案

 * OperationContractに、IsOneWayをtrueに設定

サンプル

[ServiceContract]
public interface IHelloWorldService
{
  // ★IsOneWayをtrueに設定
  [OperationContract(IsOneWay=true)]
  void SayHello();

参考文献

https://devlights.hatenablog.com/entry/20111023/p1

■ WCFトレースログの有効化するには...

 * 開発中でSOAPの内容などを出力する

解決案

 * 構成エディターツール (SvcConfigEditor.exe)で、App.configを修正する
 => 自分の環境にあるか、まずは、「C:\Program Files」又は「C:\Program Files (x86)」配下で
    「SvcConfigEditor.exe」を検索してみる
https://docs.microsoft.com/ja-jp/dotnet/framework/wcf/configuration-editor-tool-svcconfigeditor-exe

手順例

[1] 構成エディターツール (SvcConfigEditor.exe)を起動して、App.configを開く
[2] 左のツリーの「診断」ノードをクリック
[3] メッセージログの有効化をクリック

参考文献

https://devlights.hatenablog.com/entry/20111029/p1

関連記事

Windowsサービス ~ 基礎知識編 ~

https://blogs.yahoo.co.jp/dk521123/31702889.html

Windowsサービス ~ Hello World編 ~

https://blogs.yahoo.co.jp/dk521123/37948659.html

【C#】【XML】C# でXMLシリアライズ・デシリアライズ ~ DataContractSerializerクラス ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/22166698.html
で、XMLシリアライズ・デシリアライズを行ったが、
XmlSerializerクラスでは、Dictionary をシリアル化できない。

色々な方法があるようだが、DataContractSerializerクラスでやるのが
一番スマートそうなので、纏める。

■ DataContractSerializerクラス

 * .NET3.0 から

使用上の注意

 * プロジェクトの参照設定に「System.Runtime.Serialization.dll」を追加する必要がある
 * シリアライズするクラスに[DataContract]属性を、フィールドに[DataMember]属性を付与する必要がある

XmlSerializerクラスとの違い

 * HashtableやDictionaryなどもシリアル化できる
 * パフォーマンスもいいらしい

■ サンプル

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace SampleForm
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      Person person = new Person()
      {
        Name = "Mike",
        Birthday = DateTime.Now,
        NumberOfFamily = 4,
        Memos = new Dictionary<int, string>()
        {
          { 1, "Hello"},
          { 2, "World!!"},
          { 3, "Thank you for everything!!"},
          { 4, "Ciao!"}
        }
      };

      var filePath = @"hello.xml";
      Write<Person>(person, filePath);

      var clonePerson = Read<Person>(filePath);
      this.label1.Text = string.Format("{0}\n{1}\n{2}\n", clonePerson.Name, clonePerson.Birthday, clonePerson.NumberOfFamily);
      foreach (var memo in clonePerson.Memos)
      {
        this.label1.Text = this.label1.Text + string.Format("\n{0} : {1}", memo.Key, memo.Value);
      }
    }
    private static T Read<T>(string filePath)
    {
      var serializer = new DataContractSerializer(typeof(T));
      using (var reader = XmlReader.Create(filePath))
      {
        return (T)serializer.ReadObject(reader);
      }
    }

    private static void Write<T>(T instace, string filePath)
    {
      var settings = new XmlWriterSettings
      {
        Encoding = new UTF8Encoding(false)
      };

      var serializer = new DataContractSerializer(typeof(T));
      using (var writer = XmlWriter.Create(filePath, settings))
      {
        serializer.WriteObject(writer, instace);
      }
    }
  }

  [DataContract]
  public class Person
  {
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public DateTime Birthday { get; set; }
    [DataMember]
    public int NumberOfFamily { get; set; }
    [DataMember]
    public Dictionary<int, string> Memos { get; set; }
  }
}

出力結果

Mike
2019/02/21 22:03:02
4
1 : Hello
2 : World!!
3 : Thank you for everything!!
4 : Ciao!


関連記事

XML関連

C# でXMLファイルを扱うには ~ 入門編 ~
https://blogs.yahoo.co.jp/dk521123/32868509.html
C# でXMLシリアライズ・デシリアライズ ~ XmlSerializerクラス ~
https://blogs.yahoo.co.jp/dk521123/22166698.html

【C#】特殊ディレクトリのパスを取得する ~ ユーザのプロファイルフォルダ etc ~

$
0
0

■ はじめに

 ユーザ毎に設定を保存する必要があり
ユーザのプロファイルフォルダ(つまり「C:\Users\[UserName]」)を取得したいので
どうやって取るか調べてみた

■ 特殊ディレクトリのパスを取得するには...

Environment.GetFolderPath(Environment.SpecialFolder.Xxxx) で取得する

■ ユーザのプロファイルフォルダの取得

 * Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) で取得する
 * .NET4.0から

サンプル

using System;
using System.Windows.Forms;

namespace SampleForm
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      this.label1.Text = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
    }
  }
}


関連記事

ユーザ情報取得 ~ コンピュータ名 etc ~

https://blogs.yahoo.co.jp/dk521123/23844430.html

【C#】ini ファイルの扱い

$
0
0

■ iniファイルとは?

 * iniファイル (イニ・ファイル) = 初期化ファイル (初期化 = INItialization)
 * 初期時のWindowsなどでの設定ファイル形式
  => レジストリ導入により使われなくなった

ファイル形式

; コメント文
[セクション名]
パラメータ名=設定値

■ C# での ini ファイルの読み書き

 * .NET の API は、用意されておらず、Win32 API を利用する

別方法

 * 以下のサイト参照
https://note.dokeep.jp/post/csharp-inifile-read/

■ サンプル

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

namespace SampleForm
{
  public partial class Form1 : Form
  {
    private const string IniFilePath = @"c:\hello-world.ini";

    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      // キーと値を書き加える
      WritePrivateProfileString(
          "Section1", "Key1", "Hello", IniFilePath);
      WritePrivateProfileString(
          "Section1", "Key2", "1234", IniFilePath);
      WritePrivateProfileString(
          "Section2", "Key1", "World", IniFilePath);

      // 文字列を読み出す
      var stringBuilder = new StringBuilder(1024);

      GetPrivateProfileString("Section1", "Key1", "default", stringBuilder,
        (uint)stringBuilder.Capacity, IniFilePath);

      Console.WriteLine("Key : {0}", stringBuilder.ToString());

      // 整数値を読み出す
      var resultValue = GetPrivateProfileInt("Section1", "Key2", 0, IniFilePath);
      Console.WriteLine("Section : {0}", resultValue);

      // 指定セクションのキーの一覧を得る
      var resultArray = new byte[1024];
      var resultArraySize = GetPrivateProfileStringByByteArray(
                  "Section1", null, "default", resultArray, (uint)resultArray.Length, IniFilePath);
      var result = Encoding.Default.GetString(resultArray, 0, (int)resultArraySize - 1);
      var keys = result.Split('\0');
      foreach (string key in keys)
      {
        Console.WriteLine("Key : {0}", key);
      }

      // 指定ファイルのセクションの一覧を得る
      var resultArray2 = new byte[1024];
      var resultSize2 = GetPrivateProfileStringByByteArray(
                  null, null, "default", resultArray2, (uint)resultArray2.Length, IniFilePath);
      string result2 = Encoding.Default.GetString(resultArray2, 0, (int)resultSize2 - 1);
      string[] sections = result2.Split('\0');
      foreach (string section in sections)
      {
        Console.WriteLine("Section : {0}", section);
      }

      // 1つのキーと値のペアを削除する
      WritePrivateProfileString("Section2", "Key1", null, IniFilePath);

      // 指定セクション内の全てのキーと値のペアを削除する
      WritePrivateProfileString("Section1", null, null, IniFilePath);

      this.label1.Text = "Done!";
    }

    [DllImport("KERNEL32.DLL")]
    public static extern uint
      GetPrivateProfileString(
      string lpAppName,
      string lpKeyName,
      string lpDefault,
      StringBuilder lpReturnedString,
      uint nSize,
      string lpFileName);

    [DllImport("KERNEL32.DLL",
        EntryPoint = "GetPrivateProfileStringA")]
    public static extern uint
      GetPrivateProfileStringByByteArray(
      string lpAppName,
      string lpKeyName,
      string lpDefault,
      byte[] lpReturnedString,
      uint nSize,
      string lpFileName);

    [DllImport("KERNEL32.DLL")]
    public static extern uint
      GetPrivateProfileInt(
      string lpAppName,
      string lpKeyName,
      int nDefault,
      string lpFileName);

    [DllImport("KERNEL32.DLL")]
    public static extern uint WritePrivateProfileString(
      string lpAppName,
      string lpKeyName,
      string lpString,
      string lpFileName);
  }
}

出力結果

Key : Hello
Section : 1234
Key : Key1
Key : Key2
Section : Section2
Section : Section1

hello-world.ini

[Section2]

【C#】【Linq】DataTable ~ DataTable で Linq する ~

$
0
0

■ DataTable で Linq する

dataTable.AsEnumerable().Where(x => x. ...) で行う

■ サンプル

using System;
using System.Data;
using System.Windows.Forms;

namespace SampleForm
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      var dataTable = new DataTable();

      dataTable.Columns.Add("area", typeof(string));
      dataTable.Columns.Add("prefecture", typeof(string));
      dataTable.Columns.Add("city", typeof(string));

      dataTable.Rows.Add("Kanto", "Tokyo", "Setagaya");
      dataTable.Rows.Add("Kanto", "Tokyo", "Shibuya");
      dataTable.Rows.Add("Kanto", "Tokyo", "Nakano");
      dataTable.Rows.Add("Kanto", "Kanagawa", "Yokohama");
      dataTable.Rows.Add("Kanto", "Kanagawa", "Kawasaki");
      dataTable.Rows.Add("Kanto", "Saitama", "Saitama");
      dataTable.Rows.Add("Kanto", "Saitama", "Fukaya");
      dataTable.Rows.Add("Kanto", "Saitama", "Koshigaya");
      dataTable.Rows.Add("Kanto", "Saitama", "Kawaguchi");
      dataTable.Rows.Add("Kyushu", "Fukuoka", "Fukuoka");
      dataTable.Rows.Add("Kyushu", "Nagasaki", "Nagasaki");
      dataTable.Rows.Add("Kyushu", "Kagoshima", "Kagoshima");

      var resultDataTable = dataTable.AsEnumerable().Where(x => x["prefecture"].ToString() == "Tokyo").AsDataView();
      this.dataGridView1.DataSource = resultDataTable;

      this.label1.Text = "Done!";
    }
  }
}

出力結果

prefecture city
------------------
Tokyo      Setagaya
Tokyo      Shibuya
Tokyo      Nakano


関連記事

DataTable関連

DataTable ~ あれこれ編 ~
https://blogs.yahoo.co.jp/dk521123/20413895.html
DataTable ~ DISTINCT / 重複した値を省くには... ~
https://blogs.yahoo.co.jp/dk521123/14321146.html
DataTable ~ 重複を気にせずカウントするには... ~
https://blogs.yahoo.co.jp/dk521123/31382607.html
DataTable ~ データテーブルのソート ~
https://blogs.yahoo.co.jp/dk521123/15231236.html
DataSet と TableAdapter について
https://blogs.yahoo.co.jp/dk521123/10415992.html

【C#】【Form】ComboBox ~ 複数コンボボックスを連動させるには ~

$
0
0

■ はじめに

複数コンボボックスを連動させることを考える
色々なスマートな方法があると思うが、オーソドックスに実装する

 * 地方-都道府県-市・区
  + 地方:関東、関西、東北、、、
  + 都道府県:東京、大阪、、、
  + 市・区:港区、横浜市、、、

■ 注意点

【1】データバインド時、 DisplayMemer, ValueMemberを事前に設定する
【2】TextChangedイベントで行う

【1】データバインド時、 DisplayMemer, ValueMemberを事前に設定する

https://netplanetes.wordpress.com/2010/04/20/comboboxforms-%E3%81%AE-datasource-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9/
より抜粋
~~~~~~~~
DisplayMember, ValueMember をセットする前に DataSource にバインドすると、
SelectedIndexChanged イベントが起動されて
ComboBox.SelectedValue の値が想定した値(ValueMember) ではなく、
バインドしている現在選択されているオブジェクトそのものになってしまいます。
~~~~~~~~
 => これで例外になり落ちた

【2】TextChangedイベントで行う

SelectedIndexChanged イベント や SelectionChangeCommitted イベント だと
変更していなくても、イベント が走ってしまう

■ サンプル



関連記事

Windows Form ~ 目次 ~

https://blogs.yahoo.co.jp/dk521123/8054245.html

コンボボックス関連

ComboBox ~ 作成編 ~
https://blogs.yahoo.co.jp/dk521123/30294576.html
ComboBox ~あれこれ編~
https://blogs.yahoo.co.jp/dk521123/20513549.html

その他

DataTable ~ DISTINCT / 重複した値を省くには... ~
https://blogs.yahoo.co.jp/dk521123/14321146.html
DataTable ~ DataTable で Linq する ~
https://blogs.yahoo.co.jp/dk521123/37976709.html

Yahooブログが終了するらしいので引越し準備

$
0
0

■ 移行先

https://promo-blog.yahoo.co.jp/close/index.html
【1】アメーバブログ(5月9日より移行可能)
【2】ライブドアブログ(5月9日より移行可能)
【3】Seesaaブログ(5月9日より移行可能)
【4】はてなブログ(7月上旬より移行可能)

比較サイト

https://ferret-plus.com/1301
http://ebloger.net/blog-comparison/

他の方法

 * FC2ブログへの引っ越し
https://www.misumisu0722blog.com/entry/3326410
https://fc2blogstaff.blog.fc2.com/blog-entry-81.html
  => とりあえず、バックアップとして引っ越してみた(結構、簡単にできた)
  => 引越しツールが混み合っている場合は1週間前後かかるとのこと
  => FC2ブログ経由で、別のブログに飛べるみたい

【トラブル】【VisualStudio】 AxoCover に関するトラブルシューティング

$
0
0

■ はじめに

 Visual Studio のカバレッジツール「AxoCover」に関するトラブルシューティングを纏める

目次

【1】AxoCoverをインストールしたら「Umm... axocover found no unit tests」と表示されてしまう
【2】x64ビルドに変更したら「Umm... axocover found no unit tests」と表示されてしまう

【1】AxoCoverをインストールしたら「Umm... axocover found no unit tests」と表示されてしまう

エラー内容

Umm... axocover found no unit tests in this solution.
Maybe you wanted to add a new unit test project and some tests?
Or, open an existing coverage report:

解決案

[1] 「AxoCover」ビューの[Settings]-[Test Settings]を選択
[2] 「Adapter mode」で「Standard」を選択
[3] リビルドする

【2】x64ビルドに変更したら「Umm... axocover found no unit tests」と表示されてしまう

テストプロジェクトを右クリックし、[ビルド]を選択し
「プラットフォームターゲット」を「x64」に変更し、
「AxoCover」ビューを表示したら、下記の「エラー内容」が表示されてしまう

エラー内容

Umm... axocover found no unit tests in this solution.
Maybe you wanted to add a new unit test project and some tests?
Or, open an existing coverage report:

解決案

[1] 「AxoCover」ビューの[Settings]-[Test Settings]を選択
[2] 「Platform」で「x64」を選択
[3] リビルドする

関連記事

カバレッジツール / AxoCover ~ 初期設定編 ~

https://blogs.yahoo.co.jp/dk521123/35768291.html

【C#】デリゲート / イベント ~ 非同期デリゲート・コールバック関数を実装する ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/31718215.html
の続き。

処理が終わったら、コールバック関数を呼び出して実行結果を得る

■ サンプル

例1

呼び出し側
using System;
using System.Runtime.Remoting.Messaging;
using System.Windows.Forms;

namespace SampleForm
{
  // 呼び出し側
  public partial class Form1 : Form
  {
    // 非同期実行するためのデリゲート
    private delegate string SampleDelegate(int sleep, string format);

    public Form1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      HeavyTask heavyTask = new HeavyTask();

      // 実行するデリゲートを作成
      SampleDelegate sampleDelegate =
          new SampleDelegate(heavyTask.DelegatingMethod);

      // コールバック関数
      AsyncCallback callback = new AsyncCallback(this.CallbackMethod);

      this.label1.Text = "Before calling BeginInvoke()";

      // 非同期実行の呼び出し
      IAsyncResult async =
          sampleDelegate.BeginInvoke(5000, "yyyy/MM/dd", callback, null);

      this.label2.Text = "Called BeginInvoke()";
    }

    // コールバック関数:スレッド終了後の処理を記述
    private void CallbackMethod(IAsyncResult async)
    {
      // AsyncResultに変換
      AsyncResult asyncResult = async as AsyncResult;

      // 非同期の呼び出しが行われたデリゲート オブジェクトを取得
      SampleDelegate sampleDelegate =
          asyncResult.AsyncDelegate as SampleDelegate;

      // 処理結果取得
      this.Invoke(new MethodInvoker(
          delegate
          {
            string result = sampleDelegate.EndInvoke(async);
            this.label3.Text = "Today is " + result;
          }));
      // 以下の処理だと「this.label3.Text = "Today is " + result;」で例外発生
      // string result = sampleDelegate.EndInvoke(async);
      // this.label3.Text = "Today is " + result;
    }
  }
}
呼び出され側
using System;

namespace SampleForm
{
  public class HeavyTask
  {
    // 非同期させたい(重たい)処理
    public string DelegatingMethod(int sleep, string format)
    {
      System.Threading.Thread.Sleep(sleep);
      return DateTime.Now.ToString(format);
    }
  }
}
出力結果
【ボタン押下直後】
Before Calling BeginInvoke()
label2
label3

【ボタン押下5秒後】
Before Calling BeginInvoke()
Called BeginInvoke()
Today is 2019/03/09

関連記事

デリゲート / イベント関連

デリゲート / イベント ~ デリゲート・delegate ~
https://blogs.yahoo.co.jp/dk521123/20916739.html
デリゲート / イベント ~ イベント・Event・基本編 ~
https://blogs.yahoo.co.jp/dk521123/21238987.html
デリゲート / イベント ~ イベント・Event・あれこれ編 ~
https://blogs.yahoo.co.jp/dk521123/19567787.html
デリゲート / イベント ~ 非同期デリゲート・バックグラウンド処理を行う ~
https://blogs.yahoo.co.jp/dk521123/31718215.html
デリゲート / イベント ~ イベント・画面と処理の分離 ~
https://blogs.yahoo.co.jp/dk521123/22499830.html
デリゲート / イベント ~ Func デリゲート ~
https://blogs.yahoo.co.jp/dk521123/33534441.html
デリゲート / イベント ~ Action デリゲート ~
https://blogs.yahoo.co.jp/dk521123/23377932.html

【C#】DataTable ~ 基本編 ~

$
0
0

■ はじめに

https://blogs.yahoo.co.jp/dk521123/10415992.html
の続き。

今回は、「基本的な使い方」「使用上の注意」をまとめる

■ 基本的な使い方

データを追加するには...

var dataTable = new DataTable();

dataTable.Columns.Add("ID", typeof(string));
dataTable.Columns.Add("Value", typeof(string));

dataTable.Rows.Add("X001", "Tokyo");
dataTable.Rows.Add("X001", "Osaka");

特定の値を取得するには...

 * いくつか方法があるが、結局は「例3:Linqを使用した場合」がいいと思う
例1:Select() を使用した場合
DataRow[] rows = this.dataSet.testTable.Select("id = true");
foreach (dataSet.testTableRow row in rows)
{
    // ★ここに処理を書く
}
例2:Whereを使用した場合
var items = this.dataSet.testTable.Where(row => row.flg == true)

foreach (var item in items)
{
    // ★ここに処理を書く
}
http://www.atmarkit.co.jp/fdotnet/basics/adonet06/adonet06_01.html
例3:Linqを使用した場合
 * 以下の関連記事も参照。
https://blogs.yahoo.co.jp/dk521123/37976709.html

■ 使用上の注意

DataTable の Clone() について

 * DataTable の Clone() は、他のクラスの Clone() と結果が違う
  => Clone() は、構造だけコピー(データはコピーされない)
  => データも含めてインスタンス生成したい場合は、 Copy() を使う
参考文献
http://teabreak.info/blog/2013/11/19/c-datatable%E3%81%AEclone%E3%81%A8copy/1596/
http://okwakatta.net/code/dst08.html

関連記事

DataTable関連

DataTable ~ 基礎知識編 ~
https://blogs.yahoo.co.jp/dk521123/10415992.html
DataTable ~ あれこれ編 ~
https://blogs.yahoo.co.jp/dk521123/20413895.html
DataTable ~ DISTINCT / 重複した値を省くには... ~
https://blogs.yahoo.co.jp/dk521123/14321146.html
DataTable ~ 重複を気にせずカウントするには... ~
https://blogs.yahoo.co.jp/dk521123/31382607.html
DataSet / DataTable ~ データテーブルのソート ~
https://blogs.yahoo.co.jp/dk521123/15231236.html
DataSet と TableAdapter について
https://blogs.yahoo.co.jp/dk521123/10415992.html
DataTable ~ DataTable で Linq する ~
https://blogs.yahoo.co.jp/dk521123/37976709.html

【C#】【Form】HScrollBar / VScrollBar ~ 独自スクロールバーの実装 ~

$
0
0

■ HScrollBar / VScrollBar

HScrollBar

 * 水平(Horizontal)方向のスクロールバー
  => つまり、横スクロールバー
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.hscrollbar?view=netframework-4.7.2

VScrollBar

 * 垂直(Vertical)方向のスクロールバー
  => つまり、縦スクロールバー
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.vscrollbar?view=netframework-4.7.2

■ 主なプロパティ

【1】Value

 * スクロール バーのスクロール ボックスの位置に対応する値(規定は、0)

【2】Minimum / Maximum

 * Valueプロパティ の 最小値/最大値
使用上の注意:Valueプロパティの取る最大値はMaximumではない
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.scrollbar.maximum?view=netframework-4.7.2
より抜粋
~~~~~~~~~~~~
最大値は、プログラムによってのみアクセスできます。
スクロール バーの値は、実行時にユーザーとの対話が最大値に到達できません。 
ユーザーの操作によって到達可能な最大値が 1 だけでなく、Maximumプロパティの値を引いた、LargeChangeプロパティの値。
~~~~~~~~~~~~
 => ユーザ操作によって到達可能な最大値は「1+ScrollBar.Maximum-ScrollBar.LargeChange」

【3】LargeChange / SmallChange

LargeChange
バーと左右端の矢印の間をクリックした場合の移動量
SmallChange
左右端/上下端の矢印をクリックした場合の移動量

■ 主なイベント

【1】ValueChanged

 * Value プロパティが変更されると発生

【2】Scroll

 * スクロールした際に発生


関連記事

Windows Form ~ 目次 ~

https://blogs.yahoo.co.jp/dk521123/8054245.html

スクロール に関するあれこれ

https://blogs.yahoo.co.jp/dk521123/37838702.html

【C#】【Form】Panel

【C#】【Form】Form に関する色あれこれ

Viewing all 860 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>