2014年12月26日金曜日

IMEからカナを取得

IME入力時に読みを別コントロールに設定できる仕様を追加して欲しいとの事。


結局、流れた案件だけど、ある程度の調査結果でも書いておきます。


(たまには技術屋らしい書き込みもしないとねσ(^_^汗


調べると、IME用のAPIを使うとの事。
で、WndProcをOverridesして操作が常道らしい。


まず、ModuleにAPI等を定義
------------------------------------------------------------
Imports System.Runtime.InteropServices


Public Module TestFuncs
#Region "API定数"
    ''' <summary>WindowMessage:WM_CHAR</summary>
    Public Const WM_CHAR As Integer = &H102
    ''' <summary>WindowMessage:WM_IME_COMPOSITION</summary>
    Public Const WM_IME_COMPOSITION As Integer = &H10F
    ''' <summary>ImmGetCompositionString用定数:GCS_RESULTREADSTR</summary>
    Public Const GCS_RESULTREADSTR As Integer = &H200
#End Region
#Region "API定義"
    ''' <summary>IMEハンドル取得</summary>
    <DllImport("Imm32.dll")> _
    Public Function ImmGetContext(ByVal hWnd As Integer) As Integer
    End Function
    ''' <summary>IMEハンドル解放</summary>
    <DllImport("Imm32.dll")> _
    Public Function ImmReleaseContext(ByVal hWnd As Integer, ByVal hIMC As Integer) As Integer
    End Function
    ''' <summary>フリガナ取得</summary>
    <DllImport("Imm32.dll")> _
    Public Function ImmGetCompositionString(ByVal hIMC As Integer, ByVal dwIndex As Integer, ByVal lpBuf As StringBuilder, ByVal dwBufLen As Integer) As Integer
    End Function
    ''' <summary>IME状態取得</summary>
    <DllImport("Imm32.dll")> _
    Public Function ImmGetOpenStatus(ByVal hIMC As Integer) As Integer
    End Function
#End Region
End Moudle
------------------------------------------------------------


あとはテキストボックス継承のコントロールを作成
------------------------------------------------------------
Imports System.ComponentModel


Public Class TestTextBox
    Inherits System.Windows.Forms.TextBox


    ''' <summary>読み設定先</summary>
    Private _YomiControl As Control = Nothing


    ''' <summary>読み設定先コントロール</summary>
    <Category("カスタム")> _
    <Description("読み設定先コントロール")>
    Public Property YomiControl() As Control
        Get
            Return _YomiControl
        End Get
        Set(ByVal value As Control)
            _YomiControl = value
        End Set
    End Property


#Region "WndProcフック"
    ''' <summary>ウィンドウプロシージャ</summary>
    Protected Overloads Overrides Sub WndProc(ByRef wm As System.Windows.Forms.Message)
        Try
            If Not _YomiControl Is Nothing Then
                Select Case wm.Msg
                    Case WM_IME_COMPOSITION
                        'IME確定
                        Dim InpStr As String = ""
                        If (CUInt(wm.LParam) And CUInt(GCS_RESULTREADSTR)) <> 0 Then
                            Dim hIM As Integer = ImmGetContext(Me.Handle.ToInt32())
                            Dim strLen = ImmGetCompositionString(hIM, GCS_RESULTREADSTR, Nothing, 0)
                            If strLen > 0 Then
                                Dim temp As New System.Text.StringBuilder(strLen)
                                ImmGetCompositionString(hIM, GCS_RESULTREADSTR, temp, strLen)
                                InpStr = temp.ToString()
                                If InpStr.Length > strLen Then
                                    InpStr = InpStr.Substring(0, strLen)
                                End If
                                Try
                                    If Not _YomiControl Is Nothing Then
                                        _YomiControl.Text = _YomiControl.Text & StrConv(InpStr, VbStrConv.Wide)
                                    End If
                                Catch ex As Exception
                                End Try
                            End If
                            ImmReleaseContext(Me.Handle.ToInt32(), hIM)
                        End If
                        Exit Select
                    Case WM_CHAR
                        '直接入力
                        Dim hIM As Integer = ImmGetContext(Me.Handle.ToInt32())
                        If ImmGetOpenStatus(hIM) = 0 Then
                            Dim InpChr As Char = Convert.ToChar(wm.WParam.ToInt32() And &HFF)
                            If wm.WParam.ToInt32() >= 32 Then
                                Dim InpStr As String = InpChr.ToString()
                                Try
                                    If Not _YomiControl Is Nothing Then
                                        _YomiControl.Text = _YomiControl.Text & InpStr
                                    End If
                                Catch ex As Exception
                                End Try
                            End If
                        End If
                        ImmReleaseContext(Me.Handle.ToInt32(), hIM)
                        Exit Select
                End Select
            End If
        Catch ex As Exception
        End Try
        MyBase.WndProc(wm)
    End Sub
#End Region
End Class
------------------------------------------------------------
とりあえずカナを取得して、指定の別コントロールに設定するソース。


2時間程度で調べて作ったものなのでバグ等があるやもしれませんがw





2014年9月23日火曜日

薬の副作用が出ちゃったよぉ

退院してからほぼ1月。


いろいろありまして。


まず、ワーファリンが効きすぎていたようで緊急で点滴。
まあ、針が血管に当たらないw
結局 足から。結構痛い。


で、血液検査の結果、甲状腺が異常だと判明。
薬(アミオダロン)の量を増やした影響らしい。
薬の種類を変更しました。


ただ、甲状腺が正常化するまで数か月必要とのこと。
心臓薬のおかげか動悸等はないのですが
体重が減る減る。
1日で2キロ近く減った時はビビりましたw
今は、なんとか喰って維持していますが・・・


また、下痢もしてるんだよねぇ
腹痛は無いのですが
水っぽいのが屁と同時にブッパッと一気に噴出しますw


これも甲状腺異常の影響のようです。


やれやれ。。。。

2014年8月9日土曜日

ICDが動いてもた

8月2日、ICDがガツンと来ました。


数日前から体調は悪く息苦しかったのですが、少し歩いて椅子に座ると
ふらーっと頭が回った気がしてすぐガツンと。


で、即、病院に連れて行ってもらうように嫁に電話。
動作後は動作前より意識がはっきりして、普通に歩ける状態。


まあ入院は覚悟してました。


で、その夜。


病室で息が出来なくなり意識も失いました。


心不全だったそうです。


気が付くと、気管挿管されてました。


前から息をすると胸から「ゴロゴロ」と音がする感覚があったのですが
気を失う前は息を吸っても肺に届く感じがまったくしなかったです。
また、数日前から横になると息苦しく、座った方が楽でした。
深呼吸も出来ない状態です。
(典型的な心不全状態だったようです)


今は深呼吸も普通にできます。
かなり肺に水が入っていたようで、利尿剤が良く効いているみたいです。


そういえば、倒れる前、体重が増えていたような気もします。


で、5日ほどCCUに居たのですが、今は一般病棟です。



2014年5月17日土曜日

VB2013ForWEBでデザインが~

次の案件をなかなか発注してくれないのでASP.NETのお勉強でも・・・
と思ってVS Express 2013 for WEB をインストール


あれ?デザインは?
HTMLをごりごり書くの?
以前のバージョンでは使えたと思ったけど・・・


ぁぁオプションでデザインが使えるようになるのね
デフォルトで使えるようにしてほしかったなw


やれやれ。。。。

2014年4月16日水曜日

.NETでのPG間共通Configの更新方法

前回の共通ConfigでのConfig更新方法
(PGは再起動しないと取得できないので要注意)


前回は複数PGから同じConfigを参照する方法(applicationSettingだけ)を書いたけど
今回は、そのConfigの更新方法
(といってもxmlを更新する処理なだけだけどw)


いきなりサンプルソース


---------------------- コンフィグ更新用SUB[例] ----------------------------
    Public Sub WriteAppConf(ByVal sName As String, ByVal sVal As String)
        '構成ファイルのパスを取得
        Dim asm As System.Reflection.Assembly = _
            System.Reflection.Assembly.GetExecutingAssembly()
        Dim appConfigPath As String
        'ファイル指定
        appConfigPath = System.IO.Path.GetDirectoryName(asm.Location) & _
                             "TestCommon.config"
        '構成ファイルをXML DOMに読み込む
        Dim xmldoc As System.Xml.XmlDocument = New System.Xml.XmlDocument()
        xmldoc.Load(appConfigPath)
        Dim xmlnode As System.Xml.XmlNode = _
           xmldoc("TestSys.TestLibs.My.MySettings")
        'ノードを探す
        Dim n As System.Xml.XmlNode
        Dim b As Boolean = False
        For Each n In node.SelectNodes("setting")
            If n.Attributes.GetNamedItem("name").Value = sName Then
                For Each nn As System.Xml.XmlNode In n.SelectNodes("value")
                    nn.InnerText = sVal
                    b = True
                Next
                Exit For
            End If
        Next
        If Not b Then
            '新しいElementの作成
            Dim newNode As System.Xml.XmlElement = doc.CreateElement("setting")
            'Attributeを作成し、追加する
            newNode.SetAttribute("name", sName)
            newNode.SetAttribute("serializeAs", "String")
            Dim newVale As System.Xml.XmlElement = doc.CreateElement("value")
            newVale.InnerText = sVal
            newNode.AppendChild(newVale)
            node.AppendChild(newNode)
        End If
        '変更された構成ファイルを保存する
        doc.Save(appConfigPath)
    End Sub
---------------------------------------------------------------------------
   共通Configファイル名 "TestCommon.config" と
   DLL名前空間APPConfigノード名 "TestSys.TestLibs.My.MySettings" を
   環境に合わせて変更すればConfig変更用モジュールの完成


使い方は
   通常AppConfig
         my.setting.XXXX = AAAA
  共通AppConfig
         WriteAppConf("XXXX",AAAA)


ただし、文字列の情報のみ保存にしています。


 
   

2014年1月13日月曜日

.NETでのPG間共通Config

別PGから同じDLLを使用したシステム開発を依頼された。
で、外部に設定値としてConfigファイルを持たせることに。

ただ、通常ではEXE単位(userSettingsだとさらにユーザ単位)にConfigを持つわけで。
全PGにDLLの情報を持たせるのはめんどくさいし
出来れば変更内容を別EXEにも反映させたい。

で、お決まりのググる作業w

まず、設定の統一化
  各PGの App.Config (コンパイル後は[PG名].exe.config)から同一のconfigファイルを参照させる
  各PGのApp.configのApplicationSettingを改造
例 改造前 各PGのApp.config
        <applicationSettings>
           <TestSys.TestLibs.My.MySettings>
               <setting name="TESTDATA" serializeAs="String">
                   <value>100</value>
               </setting>
           </TestSys.TestLibs.My.MySettings>
        </applicationSettings>
 ↓
  改造後 各PGのApp.config
        <applicationSettings>
           <TestSys.TestLibs.My.MySettings configSource="TestCommon.config"/>
        </applicationSettings>

     共通のConfigファイル(ここでは仮にTestCommon.config)
           <TestSys.TestLibs.My.MySettings>
               <setting name="TESTDATA" serializeAs="String">
                   <value>100</value>
               </setting>
           </TestSys.TestLibs.My.MySettings>
これで同一ファイルへの参照が可能

でPGから設定内容を変更したい場合はTestCommon.configを直接変更かける仕組みを
追加する
 内容はSystem.Xml.XmlDocument でxmlファイルへ出力



2014年1月11日土曜日

色選択用コンボボックス

PGから色を指定できる仕様にして欲しいとの依頼。
Configファイルでの指定では駄目らしい。

うむ。めんどくさい。
ColorDialogを出しても良いけど、色指定が微妙。
簡単に指定が良いなぁ・・・

で、ネットを検索して、コンボボックスを自分で描写する事に。

以下がそのソース
コンボボックスの継承クラスです。

################### ソースここから #################
Imports System.ComponentModel

''' <summary>
''' 色選択コンボボックス
''' </summary>
Public Class ColorComboBox
    Inherits System.Windows.Forms.ComboBox

#Region "内部変数"
    ''' <summary>カラー色表示</summary>
    Private _DispColorName As Boolean = True
    ''' <summary>サンプル文字</summary>
    Private _SampleString As String = ""
#End Region
#Region "プロパティ"
    ''' <summary>
    ''' カラー色表示
    ''' </summary>
    <Category("表示")> _
    <Description("色名の表示設定")> _
    Public Property DispColorName() As Boolean
        Get
            Return _DispColorName
        End Get
        Set(ByVal value As Boolean)
            _DispColorName = value
        End Set
    End Property
    ''' <summary>
    ''' サンプル文字
    ''' </summary>
    <Category("表示")> _
    <Description("色指定でのサンプル文字")> _
    Public Property SampleString() As String
        Get
            Return _SampleString
        End Get
        Set(ByVal value As String)
            _SampleString = value
        End Set
    End Property
#End Region

#Region "コンストラクタ"
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    Public Sub New()
        MyBase.New()
        '固定プロパティ
        Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
        Me.DropDownStyle = ComboBoxStyle.DropDownList
        '色設定
        Me.Items.Clear()
        For Each col As KnownColor In [Enum].GetValues(GetType(KnownColor))
            Me.Items.Add(Color.FromName(col.ToString))
        Next
    End Sub
#End Region

#Region "イベント"
    ''' <summary>
    ''' 行描写
    ''' </summary>
    Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
        '領域
        Dim rCol As RectangleF
        Dim rText As RectangleF
        Dim rTextBack As RectangleF
        If DispColorName Then
            '色名あり
            Dim rWid As Single = 30
            If rWid > CSng(e.Bounds.Width * 0.9) Then
                rWid = CSng(e.Bounds.Width * 0.9)
            End If
            rCol = New RectangleF(e.Bounds.Left, e.Bounds.Top, rWid, e.Bounds.Height)
            If (rWid + 10) > e.Bounds.Width Then
                rWid = 0
            Else
                rWid = 10
            End If
            rText = New RectangleF(rCol.Right + rWid, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height)
            rTextBack = New RectangleF(rCol.Right, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height)

        Else
            '色名なし
            rCol = New RectangleF(e.Bounds.Left, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height)
            rText = New RectangleF(e.Bounds.Left, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height)
            rTextBack = New RectangleF(rCol.Right, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height)
        End If
        If e.Index >= 0 Then
            '外枠   
            Using brush As New SolidBrush(Me.BackColor)
                e.Graphics.FillRectangle(brush, rTextBack)
            End Using
            '選択色   
            Dim objColor As Color = DirectCast(Me.Items(e.Index), Color)
            If DispColorName Then
                '色名称
                Dim txt As String = objColor.ToKnownColor.ToString
                Dim fmt As StringFormat = CType(StringFormat.GenericDefault.Clone, StringFormat)
                fmt.Alignment = StringAlignment.Near
                fmt.LineAlignment = StringAlignment.Center
                Using brush As New SolidBrush(Me.ForeColor)
                    e.Graphics.DrawString(txt, e.Font, brush, rText, fmt)
                End Using
            End If
            '色枠  
            Using backBrush As New SolidBrush(objColor)
                e.Graphics.FillRectangle(backBrush, rCol)
            End Using
            'サンプル文字
            Dim Samplefmt As StringFormat = CType(StringFormat.GenericDefault.Clone, StringFormat)
            Samplefmt.Alignment = StringAlignment.Center
            Samplefmt.LineAlignment = StringAlignment.Center
            Using brush As New SolidBrush(Me.ForeColor)
                e.Graphics.DrawString(Me.SampleString, e.Font, brush, rCol, Samplefmt)
            End Using
        End If
    End Sub
#End Region

End Class

################### ソースここまで #################

プロパティを2つほど追加しています。
DispColorName  色名称の表示ON/OFF
SampleString       色にかぶせるサンプル文字

で、設定・取得は SelectItem を使用(colorオブジェクトでね)

いつもの通り、即席での作成です。
バグ等があるやも知りませんがwww