2011年1月28日金曜日

【VB.NET】フォームがコードのようなアイコン表示になりデザインが開けなくなった

ありますよね。時々。原因は不明ですが。

その時の原因はプロジェクトがクラスをフォームとして認識していない場合です。
VBからは直接直せないので、 vbproj のファイルをテキストエディタやメモ帳で開きましょう。

クラスはこのように記述されています、
<compile Include="clsUpdate.vb" />

フォームの場合は通常、このように記述されています。
<compile Include="frmMain.vb">
      <subtype>Form</SubType>
</Compile>

原因はこのフォームの中の

<subtype>Form</SubType>

がいつの間にか消えてしまうことが原因なんです。

確認してみてくださいね。

2011年1月24日月曜日

【VB.NET】Formを継承した場合にデザイン時でも継承元のLoadイベント実行への対処

Formを継承すると
なんと、継承元のFormに存在するLoadイベントが
継承したFormのデザイン時に自動実行されてしまいます。
これは私もハマりました。。


継承元のLoadイベントにて、ユーザー名の取得や画面名の取得、権限コードの取得など
データベースのデータを取得するコードを記述していると具合が悪いです。

その場合、デザイン時は処理したくないので、以下のコードを継承元FormのLoadイベントの最初に挿入します。

Private Sub FormName_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'デザイン時は処理しない
        If AppDomain.CurrentDomain.FriendlyName = "DefaultDomain" Then
            Exit Sub
        End If
End Sub

これで継承元のLoadイベントがデザイン時に動きません。

2011年1月23日日曜日

【VB.NET】プログラムリファレンス作成のSandCastle

Java でいう JavaDoc のようなプログラムリファレンスを作るためのソフト。
SandCastle





SandCastle を使用するために見ればいいリンクを羅列。

・まずSandcastle本体。

Sandcastle-June 2010 Release (Version 2.6.1062.1)
http://sandcastle.codeplex.com/releases/view/47665

・パッチをあてておこう

Sandcastle June 2010 (2.6.10621.1) Patch - Rev 1
http://sandcastlestyles.codeplex.com/releases/view/47767

・GUI環境を導入しよう

Sandcastle Help File Builder
http://shfb.codeplex.com/

・使い方を説明して頂いているリンク
http://blogs.wankuma.com/esten/archive/2007/09/12/95500.aspx
http://d.hatena.ne.jp/Wacky/20071007/1191782352


・通常に出力するとかなり時間がかかるのでMSDNへのリンクを切って高速化
http://narista.cocolog-nifty.com/gk/2007/06/sandcastle_f67f.html
※SdkLinkType が○○SdkLinkTypeとたくさんあるので注意


このソフトを使わない場合、プログラムのコメントはバラバラだわ、
プログラム内容の説明資料は作らないといけないだわ、
作った後も同期化しないといけないだわ、
と良いことなしですが、

メンバーにコメントをつける癖も付けられそうですし、すこぶる楽になりますね。

自分もリンクを忘れないようメモです。

GUIを使うやり方でやりましたが、CUIのコマンドラインでできるようになれば、
Windowsのタスクに組み込んで定期的に更新されるよう作れたりしますね。
非常に便利!

2011年1月22日土曜日

【VB.NET】PixivDownLoadBrowser ver.1.3 Update!

PixivDownLoadBrowser ver.1.3 を更新しました。
http://www.vector.co.jp/soft/winnt/net/se484370.html
【更新内容】
・R-18漫画のダウンロードエラーを修正
・画面レイアウトの修正
・コメント情報取得を修正
・イラストタイトルの最後にスペースが入っているダウンロード不具合を修正
・イラスト名に ? が入っている場合にエラーになる不具合修正
・Ctrl + D でダウンロードショートカット
・コピーや貼り付けなどのショートカット制限を解除
・自動ログインを修正


また全国誌である iP! 2月号に載りました!
小さいですが、これも一歩です!

2011年1月21日金曜日

【VB.NET】データテーブルのRowStateで変更されていないデータはUnChangedに設定する

DataTable にて、一度編集して、
また元の値に戻した場合RowStateが Modified になってしまいます。
一度編集したとはいえ、やはり全く同じ値ならばUpdateは走らせたくありませんよね!

その場合は、以下の関数をコピペして使ってみてください。

Public Sub RowStateSetUnChanged(ByVal dt As DataTable)

        If IsNothing(dt) Then
            Return
        End If

        For RowIdx As Integer = 0 To dt.Rows.Count - 1
            Dim dr As DataRow = dt.Rows(RowIdx)

            If dr.RowState <> DataRowState.Modified Then
                Continue For
            End If


            Dim IsUnChanged As Boolean
            IsUnChanged = True


            For ColIdx As Integer = 0 To dt.Columns.Count - 1
                If Not dr.Item(ColIdx, DataRowVersion.Current).Equals(dr.Item(ColIdx, DataRowVersion.Original)) Then
                    IsUnChanged = False
                    Exit For
                End If

            Next ColIdx

            ' 変更されていなかった場合、UnChangedに設定する
            If IsUnChanged Then
                dr.AcceptChanges()
            End If
        Next RowIdx
    End Sub

よろしくどうぞー。

【VB.NET】DataGridViewのTextBoxCellで入力バイト数制限をする

今回はDataGridViewについてです。

DataGridView は通常文字数での入力制限です。
しかし、対してデータベースはバイト数の桁数となっていますので、
バイト数の入力制限がDataGridViewにも必要です。

その場合、以下のコードでバイト数制限が可能です。

#Region "バイト数文字制限"
    ''' 
    ''' テキスト変更時のイベントハンドラを追加
    ''' 
    ''' ''' ''' EditingControlが表示された時の処理
    Private Sub CommonDataGridView_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles Me.EditingControlShowing
        Select Case True
            Case TypeOf e.Control Is DataGridViewTextBoxEditingControl, TypeOf e.Control Is DataGridViewComboBoxEditingControl
                'TextChangedイベントハンドラを追加
                AddHandler EditingControl.TextChanged, AddressOf EditingControl_TextChanged


        End Select
    End Sub

    Private Sub EditingControl_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)

        Select Case True
            ' TextBox
            Case TypeOf Me.FindForm.ActiveControl Is DataGridViewTextBoxEditingControl
                Dim EditingControl As DataGridViewTextBoxEditingControl
                EditingControl = DirectCast(Me.FindForm.ActiveControl, DataGridViewTextBoxEditingControl)
                Dim CurrentCell As DataGridViewTextBoxCell
                CurrentCell = DirectCast(Me.CurrentCell, DataGridViewTextBoxCell)
                Dim ValueByteCount As Integer

                ValueByteCount = System.Text.Encoding.GetEncoding("Shift_JIS").GetByteCount(EditingControl.Text)
                If ValueByteCount > CurrentCell.MaxInputLength Then
                    EditingControl.Text = LeftB(EditingControl.Text, CurrentCell.MaxInputLength)
                    EditingControl.SelectionStart = EditingControl.TextLength
                End If

                ' ComboBox
            Case TypeOf Me.FindForm.ActiveControl Is DataGridViewComboBoxEditingControl
                ' 必要の都度、型ごとに増やしていく
        End Select

    End Sub

    ' 左からバイト数で文字列を取得 これは他の共通クラスで持たせてください。
    Private Function LeftB(ByVal value As String, ByVal length As Integer) As String
        Dim enc As System.Text.Encoding
        enc = System.Text.Encoding.GetEncoding("Shift_JIS")
        Dim bytes As Byte()
        bytes = enc.GetBytes(value.PadRight(length))
        Return enc.GetString(bytes, 0, length)
    End Function
#End Region

動きとしては、DataGridViewで、編集状態に入った時に
EditingControl が生成(?)されます。
その時のイベントでEditingControlにテキストチェンジのイベントを与えます。
そこで入力制限をすれば各セルにバイト制限持たせられます。

2011年1月17日月曜日

【Android】AdMobが表示されない場合にAdMakerを表示するクラス

前に使ったクラスを晒します。

package jp.dd0125.common;

import jp.co.nobot.libYieldMaker.libYieldMaker;
import android.app.Activity;
import android.util.Log;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;

import com.admob.android.ads.AdListener;
import com.admob.android.ads.AdView;

public class CommonAdMob_AdMaker {
 private static final String TAG = "CommonAdvertisement";

 ProgressBar pb;
 AdView adView;
 libYieldMaker adMaker;
 Activity act;
 public CommonAdMob_AdMaker(Activity act){
  this.act = act;

  pb = new ProgressBar(act);
  pb.setVisibility(ProgressBar.VISIBLE);


  //pb.setGravity(android.view.Gravity.RIGHT);
  pb.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

 }




 public void createAdMob(int align){
        adView = new AdView(act);
        adView.setVisibility(android.view.View.VISIBLE);
        adView.requestFreshAd();

        adView.setGravity(align);
        adView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));


        adView.setAdListener(new AdListener() {

            public void onReceiveRefreshedAd(AdView adView) {
                Log.d(TAG, "AdListener.onReceiveRefreshedAd called!");
            }

            public void onReceiveAd(AdView adView) {
                Log.d(TAG, "AdListener.onReceiveAd called!");
                // 広告が表示できたのでProgressBarを消す
                pb.setVisibility(ProgressBar.GONE);
            }

            public void onFailedToReceiveRefreshedAd(AdView adView) {
                Log.d(TAG, "AdListener.onFailedToReceiveRefreshedAd called!");
            }

            public void onFailedToReceiveAd(AdView adView) {
                Log.d(TAG, "AdListener.onFailedToReceiveAd called!");
                // プログレスバーを消す
                pb.setVisibility(ProgressBar.GONE);


                // AdMaker の広告を設定している場合、AdMakerの広告を表示するのでAdViewの更新を行わせない
                if(adMaker != null){
                    adView.setRequestInterval(0);
                    adView.setVisibility(AdView.GONE);

                    // AdMakerの広告を表示させる
                    adMaker.setVisibility(libYieldMaker.VISIBLE);
                    adMaker.startView();

                }
            }
        });
 }

 public void createAdMaker(String url){
  adMaker = new libYieldMaker(act);
        adMaker.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));

        adMaker.setActivity(act);
        adMaker.setUrl(url);

 }
 public RelativeLayout getAdMob_AdMaker(){
  RelativeLayout layout = new RelativeLayout(act);
  layout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));

  layout.setGravity(android.view.Gravity.CENTER);
  layout.addView(pb);
  if(adView != null){
   layout.addView(adView);
  }
  if(adMaker != null){
   layout.addView(adMaker);
   if(adView == null) {
    pb.setVisibility(ProgressBar.GONE);
    adMaker.setVisibility(libYieldMaker.VISIBLE);
    adMaker.startView();
   }
  }
  return layout;
 }
}

このように使います。

// 広告
 //AdManager.setTestDevices( new String[] {
 //  AdManager.TEST_EMULATOR,
 //  //"XXXXXXXXXXXXXXXXXXXX",
 //  });
 LinearLayout l_ad = (LinearLayout)findViewById(レイアウトID);
 CommonAdMob_AdMaker Ad;
 Ad = new CommonAdMob_AdMaker(this);
 Ad.createAdMob(RelativeLayout.ALIGN_TOP); // AdMobを生成
 Ad.createAdMaker("http://stg-images.ad-maker.info/sample-test.html"); // AdMakerを生成

 l_ad.addView(Ad.getAdMob_AdMaker()); // 広告を持ったレイアウトが返ってきますので addViewします

ただし、
・res/values/attr.xml
・AdMob と AdMaker の jarライブラリ組み込み
は必要です。

【Android】HandMemo 0.5 をアップデートしました。

HandMemo 0.5

機能としては、中断時に自動保存機能を追加しました。
これで気軽にメモを中断し、その後、またメモの続きを行うことができます。

HandMemo : かんたん手書きメモ!Androidアプリ1215
http://octoba.net/archives/20101129-handmemo-android-1215.html

【Windows】IEの右クリックに自作アプリケーションの起動の登録

レジストリの
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt
に新しいキーを登録する。

キー名に右クリックに表示される名称になります。
規定の値に実行するhtmlファイル。

ContextsというDWORD値により、リンクで開くかページ内で開くか画像で開くかを設定できます。


実行するものは直接アプリケーションでは動かないようです。
htmlにスクリプトを記述し、その中でexeファイルなどを起動します。







【スクリプト】

・ファイル実行
・ページ遷移
・InnerHTML取得
・右クリックしたリンク先の取得
・選択文字取得
・タグ名取得

などできるようです。

何かに応用利くかどうか考え中。

【VB.NET】ExitException

今回はエラー処理のお話です。


Public Function A()
        Try
            If Not AA() Then
                Return False
            End If

            ' なんらかの処理

        Catch ex As Exception
            MessageBox.Show("A にてエラーが発生しました。", "エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Return False
        End Try

        Return True
    End Function

    Public Function AA() As Boolean
        Try
            If Not AAA() Then
                Return False
            End If

            ' なんらかの処理

        Catch ex As Exception
            MessageBox.Show("AA にてエラーが発生しました。", "エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Return False
        End Try

        Return True
    End Function

    Public Function AAA() As Boolean
        Try

            ' なんらかの処理

        Catch ex As Exception
            MessageBox.Show("AAA にてエラーが発生しました。", "エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Return False
        End Try

        Return True
    End Function
つまりこんな感じの処理です。
A関数処理
 AA関数処理
  AAA関数処理
 AA関数処理
A関数処理
AAA関数でエラーが発生した場合、AAの後の処理は行ってはいけないわけです。 行わないように
If Not AAA() Then
                Return False
            End If
と記述し、エラーの場合は即座に親関数に戻しています。

私はこの記述が面倒くさいと考えました。

面倒な理由は

・ If Not ~ という記述を毎回行わないといけない。
・ エラーメッセージの記述が面倒。メンテナンスも面倒。


そこで考案した方法は、
Public Class ExitException
        Inherits Exception
        Public Sub New(Optional ByVal ErrMsg As String = "エラーが発生しました。")
            MyBase.New(ErrMsg)
        End Sub
        Public Sub New(ByVal ErrMsg As String, ByVal ex As Exception)
            MyBase.New(ErrMsg, ex)
        End Sub
    End Class

    Public Function A()
        Try
            Call AA()

            ' なんらかの処理

        Catch ex As Exception
            ErrMsg(ex, "A にてエラーが発生しました。")
            Throw New ExitException
        End Try

        Return True
    End Function

    Public Function AA() As Boolean
        Try
            Call AAA()

            ' なんらかの処理

        Catch ex As Exception
            ErrMsg(ex, "AA にてエラーが発生しました。")
            Throw New ExitException
        End Try

        Return True
    End Function

    Public Function AAA() As Boolean
        Try

            ' なんらかの処理

        Catch ex As Exception
            ErrMsg(ex, "AAA にてエラーが発生しました。")
            Throw New ExitException
        End Try

        Return True
    End Function

    Public Sub ErrMsg(ByVal ex As Exception, Optional ByVal Message As String = "")
        If TypeOf ex Is ExitException Then
            Exit Sub
        Else
            If Message = "" Then
                ' メッセージを指定していない場合
                Message = "不正なエラーが発生しました。"

                ' 実行関数名取得してメッセージに含める。これに関してはまた改めて・・
            End If

            MessageBox.Show(Message, "エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

        End If

    End Sub
です。 まず、 if Not ~ の記述がなくなっています。

そして共通エラークラスとして ExitException というのが増えており、 ErrMsgという共通関数が増えています。

ExitException ・・・ 発生した場合、エラーメッセージを表示しないエラー。素通りのエラー。
ErrMsg     ・・・ エラーメッセージを表示する関数。ログ書き込みとかもここで実装していいかもしれません。
クラス化してログ書き込みパラメータとかにするともっといいかもしれませんね。

Throw New ExitException を実行するとエラーメッセージを出さずに親の関数にエラーを通知できると考えれば良いと思います。

また、ErrMsgなどで呼び出し元の実行関数名を取得することもできるので、エラーメッセージやログに活用することもできます。


とりあえず少し走り書きで書きましたが、ここまで。