2011年12月17日土曜日

【Android】ウィジェットを確実に更新させる

Androidのウィジェットの内容を更新する場合、以下のように
updateAppWidgetとすると思います。

    private void updateAppWidget(Context context, RemoteViews remoteViews) {
        ComponentName thisWidget = new ComponentName(context, ClockAppWidgetProvider.class);
        AppWidgetManager manager = AppWidgetManager.getInstance(context);
        manager.updateAppWidget(thisWidget, remoteViews);
    }

ただ、複数配置した時など、各ウィジェットへ確実に更新が行われないようです。
特に時計ウィジェットだと顕著です。

その場合、

int[] appWidgetIds = manager.getAppWidgetIds(thisWidget);
for (int i : appWidgetIds) {
    manager.updateAppWidget(i, remoteViews);
}

のように各ウィジェットIDに対して更新するようにすると、確実に更新されるようです。

ただし、重いです。。何が原因で重いのかはまだわからないですが、、、

2011年12月16日金曜日

【Android】ダイアログで画面外を触った場合に閉じる

ダイアログは2種類ある。

通常の Dialog を継承しているもの。
Activityにtheme (@android:style/Theme.Dialog など) を設定してDialog風にしているもの。

指定の方法がそれぞれ違う。



1. 通常の Dialog を継承しているもの。
final AlertDialog dialog = alertinformation.create();
dialog.setCanceledOnTouchOutside(true);

Dialog に対して、setCanceledOnTouchOutside を設定してやるといい。

2. Activityにtheme (@android:style/Theme.Dialog など) を設定してDialog風にしているもの。
    // ウィンドウ外を触った場合、閉じる
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Rect dialogBounds = new Rect();
        getWindow().getDecorView().getHitRect(dialogBounds);

        if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
            this.finish();
        }
        return super.dispatchTouchEvent(ev);
    }

イベントで画面外をタッチしている場合に画面を終了する。

2011年12月15日木曜日

【Android】Proguard使用時の注意点

Proguard使用時の注意

元々Android用ではないため、Javaのソースのみを難読化し、
XMLは無視する様子。

そのため、難読化しないクラスを除外設定しないといけない。

proguard.cfg に設定があるので編集する。

1. クラス名の難読化除外。

おすすめ
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keep public class * extends android.view.View
-keep public class * extends android.support.v4.app.Fragment

この場合、クラス名は何でもよくてandroid.view.View、またはその子を継承しているもの
-keep public class * extends android.view.View

2. メソッド名の難読化除外

xml に android:onClick がある場合、xmlは難読化しないのでjavaのメソッド名も除外に指定する。

-keepclassmembers class * {
public void On*Click(android.view.View);
public void on*Click(android.view.View);
}

そのため、onClickメソッドはやっぱり on*Click という命名規則にした方が良い。

2011年11月4日金曜日

【Android】ProgressBarをコードで作成時にバー状態にする

ProgressBarをコードで作ると style が変更できないように見えます。
どうやら以下の方法で変えれるみたいです。
styleと名のつくものは全てそうかも。ていうかこれはテーマってことかな?

ProgressBar progress = new ProgressBar(this,null,android.R.attr.progressBarStyleHorizontal);

コンストラクタの第3引数で設定したらいいみたい。
android.R.attr.progressBar~ に他のスタイルもあります。

他に xml でProgressBarを定義して Inflate する方法でもいいですね。

2011年8月16日火曜日

【Chrome】Google Chrome拡張の保存先

Windows XPだと

C:\Documents and Settings\[ユーザー名]\Local Settings\Application Data\Google\Chrome\User Data\Default\Extensions

というところにある。

まあ、他のOSでも、 background.html とかで検索するときっとどっかに大量のファイルがヒットします。
そこに拡張のソースが見れる形であるので、参考になります。

2011年7月28日木曜日

第3回SHARPハッカソンに行ってきました

7月23日、24日の土日にて 第3回SHARPハッカソンに行ってきました。

私としては初めてのハッカソンだったため、ドキドキしながら行ってきました。
場所は広島の八本松。
名古屋から広島まで新幹線に乗っていき、そこから鈍行に乗り、八本松までという長い道のりでした。


参加者はテレビで見たならぬ、ネットで見たことある!という豪華メンバー多数。
今まで会ってみたいなって思ってた人にも会えました。
こんなすごい人達と一緒に参加できることが大変ありがたかったです!

ハッカソンでは
SHARPさんから2011年夏モデルの最新端末をお借りし、
チームで2日間の期間を使い、アイデア出しからアプリを完成するところまでするというものでした。

自分たちのチームは、   TEAM びすこ。
メンバーは、
デザイナー
 @korowan
 @rie05
開発者
 @itog
 @dd0125 (自分)
という構成でした。

デザイナーさんがいるということは新鮮でした!

アイデアとしては色々候補はあったのですが
せっかくSHARPのイベントなので、SHARP API と使おうということで、

歩数計APIでコインを貯め、開閉通知APIで動かすスロットということで決定。
@rie05 さんの ウキウキノコ というキャラクターを使わせてもらいました。

1日目、1日目の夜、2日目と開発を頑張った結果がこれ。


うちのチームは39分から!



最後に一番面白かったチームはということで投票をするのですが、
な、な、なんと準優勝を頂けました。
頑張ったことは確かですが、皆さんすごかったのでいいのかなーって思いながらでした。
すごく嬉しかったです。





帰りは広島焼きを食べて帰りました。

よし、最後に広島らしいことした!



・今回感じたこと

デザイナーと開発者が混ざると科学反応が起きるということ。

開発者はデザイナーさんが作った綺麗な画像を動かせることに感動。
デザイナーさんは自分が作ったものが動くことに感動。
双方いい影響を与えてる!

またハッカソン参加したいなーって思いました。^^

SHARPのみなさん、ブリリアントサービスのみなさん!
そして参加者のみなさん、メンバーのみなさん、ありがとうございました!


イベントについて更に詳しくはこちらのブリリアントサービスさんのブログで
http://d.hatena.ne.jp/bs-android/20110727

2011年7月21日木曜日

【Android】他パッケージのActivityを呼び出すには

例えば電池使用量の画面を出すには、結論から言うと、
Intent intent = new Intent(Intent.ACTION_MAIN);
        ComponentName compo = new ComponentName("com.android.settings","com.android.settings.fuelgauge.PowerUsageSummary");
        intent.setComponent(compo);
        startActivity(intent);

・ComponentName に パッケージ名とクラス名を設定しています。

他の画面はどうやって出すの?って気になった場合は

なにか画面を起動したときに出る、
LogCatの
07-21 02:47:06.246: INFO/ActivityManager(116): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.contacts/.DialtactsActivity bnds=[5,244][115,362] } from pid 1016
を参照し、 cmp=com.android.contacts/.DialtactsActivity となってるのが、
パッケージ名とクラス名。ちなみにこれは電話アプリ。

この場合は、
ComponentName("com.android.contacts","com.android.contacts.DialtactsActivity");
となる。

これで電話アプリが起動する。

2011年7月19日火曜日

【Android】文字列から id(int型) を取得する

現在のActivityのパッケージリソースから取得する場合は、

R.string.XXXXX というリソースでは、

int resid = getResources().getIdentifier("XXXXX","string",this.getPackageName());

と取得。

R.drawable.YYYY では、

int resid = getResources().getIdentifier("YYYY","drawable",this.getPackageName());

で取れる!

2011年6月29日水曜日

【Android】viewのidからid名を取得する

Context.getResources().getResourceEntryName(view.getId())

コードハイライト使う必要ないねw

2011年6月23日木曜日

【ブログ】ファイルのアップロード

ブログでファイル(ソースコードや実行ファイル)をアップロードしたい時、
どうしようかなと困っていたけども解決策を発見。

DropBoxのPublic機能を使えばいいんだと思った!

全体公開のフォルダを作成し、その中にファイルを置き、
全体公開フォルダの操作から 「共有リンクを入手」

取得した共有リンクをブラウザからアクセスし、
ファイルのリンク先をブログに使用!

ブログを見ているユーザーがリンクをクリックすると
1クッション画面を挟んでくれるし、便利ー。

うちの共有だとこんな感じ


DropBoxだとエクスプローラからファイルいじれたりもするしね^^

2011年6月22日水曜日

【Windows】PuTTYの画面を最大化する方法

普通に使ってて、起動したばかりの標準のウィンドウの大きさは小さい。
毎回大きくするのは面倒。

どうすればいいかとPuTTYの設定を見直していたが、
そこにはない。

というか、通常のWindowsのショートカットのプロパティで
"実行時の大きさ" を "最大化" にすれば良かっただけだった。

簡単なことでした。

他のショートカットもそういえばそうだなー。

2011年6月21日火曜日

configure: error: mysql_query missing!?

centos に pdo_mysql を入れる時に
./configure すると
configure: error: mysql_query missing!?
が出てすごい困ってたのだが、

yum install mysql-devel で

mysql-devel をインストールしてから
./configure すると
うまくいった!

【VB.NET】Windowsの起動と終了の時間を表示

会社で勤怠を付け忘れると、
昨日の出社時間と退社時間がいつだっけ・・って忘れる時がある。

出社と同時にPCつけ、退社と同時にPCを消しているという条件であれば、
そんな時には Windowsのイベントログを見ると起動と終了時間がすぐにわかる。

イベントID 6005 と 6006 を見ればいいみたい。

VB.NET のソースではこんな感じ。

Dim logs() As System.Diagnostics.EventLog
        logs = System.Diagnostics.EventLog.GetEventLogs()
        For Each log As EventLog In logs
            If log.LogDisplayName <> "システム" Then
                Continue For
            End If

            For Each entry As EventLogEntry In log.Entries
                Select Case entry.EventID
                    Case 6005 ' 起動
                        Console.WriteLine("起動 " & entry.TimeWritten)
                    Case 6006 ' 終了
                        Console.WriteLine("終了 " & entry.TimeWritten)
                        Console.WriteLine()

                    Case Else
                        Continue For
                End Select
            Next entry
        Next log

作ったものはこれ。
ここをクリック


実行するとWindowsの起動時間と終了時間を教えてくれます。
GUIとか作ったって仕方ないのでコマンドラインアプリケーションですが、
便利だと思われ。

2011年6月19日日曜日

【Chrome】URL 1up

Chrome Store に拡張を初めて出してみました。

すっごく簡単な拡張ですが、
私、昔はSleipnirユーザーで(今もサブで使っていますが)して、
「一つ上のフォルダへ」というボタンを結構重宝していました。

あれは色んなサイトでHOMEに移動する時などに便利なんですよねー。

ただし、現在よく使ってるChromeにはそのボタンがない!

まぁ、ないのが普通だとは思うんですけど。笑

ないなら作ろうということで作ってみました!

URL 1up

ソースコードは10行くらい?

簡単ですが、自分は使います。

まさに俺得。

いいんじゃないでしょうか。

使いたい人はよしなに使ってくださいな。

【垂れ流し】ニコニコ動画用の小さなChrome拡張を作る

ニコニコ動画用の小さなChrome拡張を作ろうとしている。

マイリスト連続再生時にブラウザを終了して、
そしてブラウザを再起動するとマイリスト連続再生は最初からになってしまう。

これはどうにか続きの動画から再生するようになる拡張を作りたい。

ニコニコ動画のHTMLソース内には
「この動画から連続再生」を選んだ場合のマイリストfromIDが保存されている。
しかし、現在の再生中の動画のマイリストfromIDは保存されていない。取得できない。

ニコニコ動画のプレイヤーはFLASHであり、
そこから値が取得出来ればいいが、よくやり方がわからない。

マイリスト再生中に
「とりあえずマイリスト一発登録」を押すと、
再生中の動画がマイリスト登録された。

と、いうことは。
FLASHで再生中の動画IDが取得できていることになる。

ソースを解析していると
BTN_add_deflist というボタンを押して addVideoToDeflistという関数が動き、
マイリスト登録されている。

そのなかで注目すべきは、
cur_thread_id。 これが動画の情報な気がする。

この値が操作されているのが、
changePlayingVideo という関数。

いかにも再生中の動画が切り替わった時に動きそうな関数。

これがどこから呼び出されているかはソース内には見つからない。

むぅ。とりあえず今日はここまで。

2011年6月15日水曜日

Chromeで入れたらいいと思うよの拡張まとめ

まとめてみましたよっと。
Chromeに入れるべき拡張。


Google Mail Checker


安心のGoogle品質!
Gmailの新着を通知してくれ、ワンクリックでGMailにアクセス。




Google Calendar Checker


安心のGoogle品質!
直近の予定をアイコンで示してくれるので便利。




Send to Google Docs


現在見ているWebページをGoogleDocsにPDFでキャプチャしてくれます。
キャプチャ結果を確認してから保存できます。




Google Quick Scroll


Googleで検索した後、ページの中で検索した語句の場所に一気にスクロールできるので便利。




Bubble Translate


Ctrlを押しながら語句を選択するだけで翻訳してくれます。




AutoPatchWork


page=1,page=2 などがあるページだと「次ページへ」をクリックしなくても勝手に1ページにつなげてくれる。
Googleやニコニコ動画などでも対応。




SmoothScroll


スクロールが気持よくなる。この微妙な感覚は入れてみないとわからない。




MyShortCuts


各種Googleサービスへのショートカットが詰まっている。




はてなブックマーク GoogleChrome 拡張


便利なソーシャルブックマーク。




英辞郎


翻訳Extension。ひとつの英単語につき、複数の意味を教えてくれるので便利。




Create Link


「 Google http://www.google.com 」 のように現在見ているページのタイトル、URLを簡単にコピーできる。
カスタマイズも可能。




Web2PDFConverter


現在見ているページをPDFに変換してダウンロードできる。





goo.gl URL Shortener


短縮URLを簡単に作成。コピーも簡単。


2011年6月7日火曜日

【EGit】Push時の設定でプロトコルに 「git + ssh」 が選べない

どこの説明のページにも git+ssh を選べって書いてあるのですが、
プロトコルのドロップダウンリストには選択肢がありませんでした。

http://www.eclipse.org/forums/index.php?t=tree&th=197431&S=60c2d429a68e03ee4836a39d94a685aa#page_top

ここに書いてある通り、
git+ssh から ssh になったようです。

ややこしや。

2011年6月2日木曜日

【Git】git show でファイルの内容確認

git show <リビジョン番号>:<ファイルパス>

で特定リビジョンのファイルが確認できる。

git show xxxxx:src/xx/xx/xx/xx/xxxx.java

みたいな感じ。

リビジョン番号はリビジョン名でもいいんじゃないかな。

2011年5月16日月曜日

【Android】日齢計算アプリ更新

日齢計算アプリを更新しました。

・入力した誕生日を保存
・TwitterなどにShareできる
・カレンダーに登録できる

そんな機能を追加しました。

でもデザインは手抜き。
もっと力を入れてやらないといけんっちゃいけんのだけど、
家にいて気が抜けるのともっと力を入れないといけないのもあるのでねぇ。。。

とりあえずやりたいとこまではできた感じ。

HandMemoのマルチタッチ時のおかしな動作も直さないといけないなー。。

2011年3月15日火曜日

【Android】祝!アンドロイダー掲載

アンドロイダーに初めて掲載されました。

レトロライツアウト!

http://androider.jp/a/601db07b8ec543c0/

実は最初のテストアプリを覗いて、一番時間をかけていないアプリなんですが、
これが掲載されました。

他のアプリも掲載されたらなぁー、って思ってます^^

2011年3月3日木曜日

【VB.NET】実行しているメソッド名を取得する

New StackFrame(0).GetMethod.Name

で取得できます。

ただやっぱり関数化したいですよね。
ログ出力に使うと思いますので。
そういう場合は、

New StackFrame(1).GetMethod.Name

ってしたらいいです。

単純。

2011年2月18日金曜日

【VB.NET】ソートされたとしてもDataGridViewの行に対応するDataRowを取得する

DataGridViewのDataSourceに BindingSource や DataTable を関連付けした場合に
DataGridViewの4行目に当たるDataTableの行を取得したい、とかやりたい時ありますよね。

通常はそのまま同じ4行目が対応する行になるのですが、
ソートをしてしまうとDataGridViewはソートされますが、DataTableはソートされず、
行番号が食い違うようになってしまいます。
その場合、下記関数をご利用ください。

#Region "DataGridViewのRowIndexからDataTableのDataRowを取得する"
        ''' 
        ''' DataGridViewのRowIndexからDataTableのDataRowを取得する
        ''' 
        ''' ''' 
        ''' ソート時など、DataGridViewのRowIndexが必ずしもDataTableのRowIndexとマッチしないため
        Public Function GetDataRow_ByDataGridViewRowIdx(ByVal RowIdx As Integer) As DataRow
            Try
                If Me.Rows(RowIdx).DataBoundItem Is Nothing Then
                    Return Nothing
                End If
            Catch ex As IndexOutOfRangeException
                Return Nothing
            End Try

            Dim Dr As DataRow
            Dim Drv As DataRowView = CType(Me.Rows(RowIdx).DataBoundItem, System.Data.DataRowView)
            Dr = CType(Drv.Row, System.Data.DataRow)

            Return Dr
        End Function


#End Region

対応するDataRowが取得できます。
これで行移動時に値の編集するなど、DataRowをいじっちゃってください。

2011年2月17日木曜日

【SQLServer】同一列名なのに桁数や列説明が食い違う他テーブルの列を抽出

同じ列名なのに他テーブルでは列説明が違ったり、
型が違ったり、桁数が違ったりする列ってちらほら出てきますよね。

発見するのが難しかったりするのでSQLを作成しました。

SELECT DISTINCT
  COL1.TABLE_NAME  AS テーブル名
,( select b.value from sys.tables a
   left join sys.extended_properties b on a.object_id = b.major_id and a.parent_object_id = b.minor_id 
   where a.name =COL1.TABLE_NAME) AS テーブル説明
, COL1.COLUMN_NAME AS 列名
, COL1.DATA_TYPE AS 型
, COL1.CHARACTER_MAXIMUM_LENGTH AS 文字桁
, COL1.NUMERIC_PRECISION AS 整数桁
, COL1.NUMERIC_SCALE AS 小数桁
, COL1.IS_NULLABLE AS NULL許容
, COMMENT.COLUMN_COMMENT AS 列説明

FROM INFORMATION_SCHEMA.COLUMNS COL1
-- コメントを取得
INNER JOIN(
select 
     t.name as TABLE_NAME
    ,c.name as COLUMN_NAME
    ,ep.value as COLUMN_COMMENT
from
      sys.tables              t
     ,sys.columns             c
     ,sys.extended_properties ep
where
      t.object_id = c.object_id
and c.object_id = ep.major_id
and c.column_id = ep.minor_id) COMMENT
ON COMMENT.TABLE_NAME = COL1.TABLE_NAME
AND COMMENT.COLUMN_NAME = COL1.COLUMN_NAME

-- 列の情報が食い違うもの
LEFT JOIN INFORMATION_SCHEMA.COLUMNS COL2
ON COL1.COLUMN_NAME = COL2.COLUMN_NAME 
AND (COL1.DATA_TYPE <> COL2.DATA_TYPE 
  OR COL1.CHARACTER_MAXIMUM_LENGTH <> COL2.CHARACTER_MAXIMUM_LENGTH 
  OR COL1.NUMERIC_PRECISION <> COL2.NUMERIC_PRECISION 
  OR COL1.NUMERIC_SCALE  <> COL2.NUMERIC_SCALE 
  )
WHERE 
(
       -- 列のコメントが食い違うもの
       (
              select  COUNT(distinct ep.value )--c.name AS COLUMN_NAME

              from
                       sys.tables              t
                     ,sys.columns             c
                     ,sys.extended_properties ep
              where
                     t.object_id = c.object_id
              and c.object_id = ep.major_id
              and c.column_id = ep.minor_id
              and c.name = COL1.COLUMN_NAME 
       group by c.name
       ) > 1
       -- 列の情報が食い違うもの のJOIN がヒットした
OR COL2.COLUMN_NAME IS NOT NULL
)

-- 列名指定する場合はここに条件
--WHERE COL1.COLUMN_NAME = 'HIN_CD'

ORDER BY COL1.COLUMN_NAME ASC


実行すると修正の必要性がある列のみ抽出されます。

Oracleでも似たようなの作っておくと便利!

※ちなみにSQLはインデントなどちゃんと直してません。

2011年2月13日日曜日

【Windows】Skypeを2重起動させる方法

2つのアカウントを使用する場合など、
Skypeは標準に起動すると2重起動できません。

もし起動させたい場合は、

"C:\Program Files\Skype\Phone\Skype.exe" /secondary

のように /secondary というオプションをつけます。

ただし、これだけだと自動ログインがきかなくなるのです。

まぁ、アカウントが複数なのでもちろんそうなのですが。

そこで起動オプションを増やします。

"C:\Program Files\Skype\Phone\Skype.exe" /secondary /username:【username】 /password:【password】

/username , /password オプションで自動ログインが可能です。
これらを含めてショートカットを作成すると、複数アカウントにて自動起動が可能です。

ただしパスワードをショートカットに書いてしまうことになるので、
そこだけ気をつけてくださいね。

2011年2月12日土曜日

【VB.NET】Date型の定数の宣言

Date型の定数の宣言は以下の通りです。

Public Const HogeDate As Date = #2/12/2011 12:00:00 PM#

# で囲んだ日付で宣言します。
中はアメリカの日付表記ですね。

ちなみに

Public Shared ReadOnly HogeDate As Date = #2/12/2011 12:00:00 PM#
のような感じでも定数みたいなやつが作れるよな感じですけど、どうなんでしょうねぇ。。

まぁ、Constでいいと思います。

2011年2月11日金曜日

【Windows】ショートカット作成時「~へのショートカット」をつけなくする

※XPにて確認しています。

Windowsにてショートカット作成した場合、

「【ファイル名】へのショートカット」
という風に勝手に へのショートカット と名前がついてしまいます。

私はこの へのショートカットは消してしまうタチです。

初めからつけなくしたらいいのではないか、ということでレジストリを変更してしまいましょう。

-------------------------------------------------------------
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
"link"=hex:00,00,00,00
-------------------------------------------------------------

パッチは ここ に置いておきます。

実行するだけでショートカット作成時に へのショートカット という名前がつかなくなります。

2011年2月10日木曜日

【VB.NET】メソッドのステップ実行をスルーさせる

CellValueChangedの中にある自作の決まりきったメソッドなど、
ステップ実行する必要はもうないのにステップ実行の中に入ってしまう時ありますよね。

その時はメソッドの前に

<System.Diagnostics.DebuggerStepThrough()>

という属性をつけてください。

付け方としましては、
<System.Diagnostics.DebuggerStepThrough()> _
Public Sub XXXX()
    ' 処理
End Sub

となります。

ちなみに、VB2010では、属性の後の次の行につながるための _ がいらなくなりますね。

2011年2月9日水曜日

【VB.NET】Formの自動TabIndex設定

フォームのコントロールのタブインデックス設定は結構面倒です。
自分的には決まり切った規則があるにも関わらず、
同じ作業の繰り返しなのでかなり面倒です。

決まり切った規則とは以下の通りです。
-----------------------------------------------------
第1条件 Top値の少ないコントロール
第2条件 Left値の少ないコントロール
※子コントロールを持つコントロールは内部も設定する
-----------------------------------------------------
この並び順でTabIndexを自動で設定してあげれば解決するんでないの、ということです。

ということで、以下の関数とプロパティを作成しました。
継承元のFormに設置してみてください。

#Region "自動タブインデックス設定"

    Private _SetAutoTabIndex As Boolean
    <System.ComponentModel.Category("追加プロパティ")> _
    <System.ComponentModel.DefaultValue(GetType(Boolean), "False")> _
    <System.ComponentModel.Description("Trueにすると画面の全コントロールのタブインデックスを自動で設定します。")> _
    Public Property SetAutoTabIndex() As Boolean
        Get
            Return _SetAutoTabIndex
        End Get
        Set(ByVal value As Boolean)
            _SetAutoTabIndex = value
            If _SetAutoTabIndex Then
                Dim UpdateCount As Integer
                UpdateCount = SettingAutoTabIndex(Me)
                MessageBox.Show(UpdateCount & "件のタブインデックスを自動設定しました。", "自動設定", MessageBoxButtons.OK, MessageBoxIcon.Information)
                _SetAutoTabIndex = False
            End If
        End Set
    End Property


    ''' <summary>
    ''' タブインデックスを自動で設定します。
    ''' </summary>
    ''' <param name="ControlsInObject">引数で渡されたコントロール(省略した場合はフォーム)</param>
    ''' <remarks></remarks>
    Public Function SettingAutoTabIndex(Optional ByVal ControlsInObject As Control = Nothing) As Integer
        If ControlsInObject Is Nothing Then
            ControlsInObject = Me
        End If
        Dim UpdateCount As Integer = 0
        Dim sl As New System.Collections.SortedList()

        ' ポジションが左上に近いコントロールから順にタブインデックスを設定する.優先順位は上、左の順
        For Each Ctrl As Control In ControlsInObject.Controls
            Try
                Select Case True
                    ' 子コントロールを持てるコントロール(タブ、パネル、グループボックス...)
                    Case HasChildControls(Ctrl)
                        sl.Add(Ctrl.Top.ToString.PadLeft(10, "0") & Ctrl.Left.ToString.PadLeft(10, "0"), Ctrl)
                        UpdateCount += SettingAutoTabIndex(Ctrl)

                    Case Else
                        sl.Add(Ctrl.Top.ToString.PadLeft(10, "0") & Ctrl.Left.ToString.PadLeft(10, "0"), Ctrl)

                End Select
            Catch ex As Exception

            End Try
        Next Ctrl
        ' タブインデックスを設定する
        For Idx As Integer = 0 To sl.Count - 1
            If CType(sl.GetByIndex(Idx), Control).TabIndex <> Idx Then
                CType(sl.GetByIndex(Idx), Control).TabIndex = Idx
                UpdateCount += 1
            End If
        Next Idx

        Return UpdateCount
    End Function
#End Region
#Region "子コントロールを持てるコントロールかどうかチェック"
    ''' <summary>
    ''' 子コントロールを持てるコントロールかどうかチェック
    ''' </summary>
    ''' <param name="Ctrl"></param>
    ''' <returns></returns>
    ''' <remarks>子コントロールを持てる場合、True。持てない場合、False</remarks>
    Public Function HasChildControls(ByVal Ctrl As Control) As Boolean
        Select Case True
            Case TypeOf Ctrl Is Panel, TypeOf Ctrl Is GroupBox, TypeOf Ctrl Is TabControl, TypeOf Ctrl Is UserControl
                Return True
            Case Else
                Return False
        End Select
    End Function
#End Region


-----------------------------------------------------
・SettingAutoTabIndex
タブインデックスを設定します。引数としてGroupBoxなど渡せばその内部のみTabIndexを設定します。

・HasChildControls
子コントロールを持っているコントロールかどうかチェックします。

・SetAutoTabIndex
プロパティとして実装しました。Booleanで持っていることに特に意味はありませんが、
Trueにしてみるとタブインデックスを自動設定し、Falseに戻ります。
(本当はプロパティグリッドにボタンを置きたいです)
-----------------------------------------------------



FormのSetAutoTabIndex のプロパティをいじくるだけで自動でタブインデックスがデザイナ上で設定します。

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などで呼び出し元の実行関数名を取得することもできるので、エラーメッセージやログに活用することもできます。


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