飴屋ぷろじぇくと

 ちょっとカテゴリを分けてみようかなっと。

--.--.--[--] スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

2014.11.26[水] xlibでデスクトップに立つ。その3

まず、画像読み込みにバグがありました。で、それを修正。
XImageのバッファは色深度24bitの時はピクセルあたり32bitになるんですが、画像ファイルが1ピクセル24ビットのとき、バッファ側の32bit幅でコピーしていたため、未使用ビットに隣のデータがコピーされてしまって、これが悪さをしてマスクの生成が上手く行ってませんでした。現象としては画像のふちに乱発的に背景色のドットが発生します。
maru10x.png
よく見ないと判らないんですが………。
修正は以下。
スポンサーサイト

2014.11.22[土] xlibでデスクトップに立つ。その2

withballoon.jpg
続編です。ここまでもっていきます。

2014.11.18[火] デスクトップを振動させる

バイブレーション機能ではありません。
ふと「デスクトップが振動したらどうだろう?」と思い立ち、作ってみた。今回はWindowsです。
多分先人がもうやってると思うけどAPIの検索含め数十分で完成。
実行すると文字通りデスクトップ全体が上下に振動します。
#include <windows.h>

int WINAPI WinMain(
        HINSTANCE hInstance ,
        HINSTANCE hPrevInstance ,
        LPSTR lpCmdLine ,
        int nCmdShow ) {
    HDC pmdc = GetDC(NULL);
    RECT rc2;
    int i;
    for (i = 0; i < 5; i++) {
        ScrollDC(pmdc, 0, 1, NULL, NULL, NULL, &rc2);
        Sleep(5);
    }
    for (i = 0; i < 12; i++) {
        ScrollDC(pmdc, 0, -1, NULL, NULL, NULL, &rc2);
        Sleep(5);
    }
    for (i = 0; i < 16; i++) {
        ScrollDC(pmdc, 0, 1, NULL, NULL, NULL, &rc2);
        Sleep(5);
    }
    for (i = 0; i < 18; i++) {
        ScrollDC(pmdc, 0, -1, NULL, NULL, NULL, &rc2);
        Sleep(5);
    }
    for (i = 0; i < 18; i++) {
        ScrollDC(pmdc, 0, 1, NULL, NULL, NULL, &rc2);
        Sleep(5);
    }
    for (i = 0; i < 16; i++) {
        ScrollDC(pmdc, 0, -1, NULL, NULL, NULL, &rc2);
        Sleep(5);
    }
    for (i = 0; i < 12; i++) {
        ScrollDC(pmdc, 0, 1, NULL, NULL, NULL, &rc2);
        Sleep(5);
    }
    for (i = 0; i < 8; i++) {
        ScrollDC(pmdc, 0, -1, NULL, NULL, NULL, &rc2);
        Sleep(5);
    }
    for (i = 0; i < 4; i++) {
        ScrollDC(pmdc, 0, 1, NULL, NULL, NULL, &rc2);
        Sleep(5);
    }
    ScrollDC(pmdc, 0, -1, NULL, NULL, NULL, &rc2);
    Sleep(5);
    
    ReleaseDC(NULL, pmdc);
    InvalidateRect(NULL, NULL, TRUE);
    return 0;
}

こんな変なことが出来てしまうWindowsの緩いとこは好きだな。X Windowで出来るのかな?
バイナリとソースはこちらから。

2014.11.17[月] xlibでデスクトップに立つ。

突然ですが、xlibというのはX Window Systemの基本的なクライアントライブラリです。
X Window SystemというのはまあUNIX系のウィンドウシステムはほぼ全部これが使われてたりする、Linux使いの人なら常識ともいえるウィンドウシステム、というかプロトコルなんですが。

と、前提知識をお知らせしたところで、今回のお題は、
StandOnDesktop.png
これです。
Xといいつつ、Mac OSXですが。
OSXはMac独自のウィンドウシステムでXは使ってないんですが、X11.appというアプリが入っていて(バージョンによってはオプション)Xウィンドウアプリを実行出来るようになっています。

まあそれはそれとして、本題のxlibプログラミングです。
今時はGTK+やらQtやらが良くこなれていて、xlibを直接使うなんて時代遅れもいい所なんですが、数年、いや十年位前か、Linuxでデスクトップに立たせるには?を調べまくって結局よく判らなくて苦渋をなめた経験がありまして。
今回、「マルチプラットフォームでウィンドウアプリを作るにはどんな選択肢があるか」を調べる一環で、Xウィンドウプログラミングも引っかかりまして、「そういやこんなの昔調べたな」とか思っていたらあれからネット上の情報も増えていて今度は比較的容易に情報が集まり実際立たせる事が出来てしまった(上の画像参照)、というわけ。以下プログラミングな話題。

2014.11.12[水] FreeBASICの#Macroをテンプレート的に使ってみるテスト2


テンプレートマクロ第二弾。マップの実装です。但しあんまり速い実装ではありません。
マップというのはキーと値のペアを登録してキーを添え字にその値を取得できるクラスのことです。
map.bi
#define Map(T,V) T##_To_##V##_Map

#Macro Declare_Map(Ky,Va)
Type Map(Ky,Va)
Private:
    m_Keys(Any) As Ky
    m_Values(Any) As Va
Public:
    Declare Property Keys(i As Integer) As Ky
    Declare Property Items(i As Integer) As Va
    Declare Sub Clear
    Declare Property Size As Integer
    Declare Function add(k As Ky, v As Va) As Integer
    Declare Function find(k As Ky) As Integer
    Declare Operator [](k As Ky) ByRef As Va
End Type
#EndMacro

#Macro Implement_Map(Ky,Va)
Property Map(Ky,Va).Keys(i As Integer) As Ky
    Return m_Keys(i)
End Property

Property Map(Ky,Va).Items(i As Integer) As Va
    Return m_Values(i)
End Property

Property Map(Ky,Va).Size As Integer
    Return UBound(m_Keys) + 1
End Property

Sub Map(Ky,Va).Clear
    Erase m_Keys
    Erase m_Values
End Sub

Function Map(Ky,Va).add(k As Ky, v As Va) As Integer
    Dim u As Integer = UBound(m_Keys)
    Dim i As Integer
    if u < 0 Then
        Redim PreServe m_Keys(0), m_Values(0)
        m_Keys(0) = k
        m_Values(0) = v
        i = 0
    Else
        Dim n As Integer
        For n = 0 To u
            if m_Keys(n) >= k Then
                Exit For
            End If
        Next
        u = u + 1
        Redim PreServe m_Keys(u), m_Values(u)
        For i = u - 1 To n Step -1
            m_Keys(i + 1) = m_Keys(i)
            m_Values(i + 1) = m_Values(i)
        Next
        m_Keys(n) = k
        m_Values(n) = v
        i = n
    End If
    Return i
End Function

Function Map(Ky,Va).find(k As Ky) As Integer
    Dim u As Integer = UBound(m_Keys)
    Dim s As Integer = 0
    Dim t As Integer = u + 1
    Dim m As Integer = u \ 2
    
    Do While t > s + 1
        If k < m_Keys(m) Then
            t = m
            m = (s + t) \ 2
        ElseIf k > m_Keys(m) Then
            s = m
            m = (s + t) \ 2
        ElseIf k = keys(m) Then
            Return m
        Else
            Exit Do
        End If
    Loop
    Return -1
End Function

Operator Map(Ky,Va).[](k As Ky) ByRef As Va
    Dim n As Integer = find(k)
    if n = -1 Then
        Dim v As Va
        n = add(k, v)
    End If
    Return m_Values(n)
End Operator

#EndMacro


キーと値はキーでソートして格納し、検索はバイナリ検索で行っています。
要素数が膨大になると登録がかなりオーバーヘッドになりますのでもっと速い実装が欲しい場合は二分木のマップやハッシュマップ等を自力で作成するこををお勧めします。

使い方の例:
#include "map.bi"

Declare_Map(String,Long)
Implement_Map(String,Long)

Dim m As Map(String,Long)
Dim i As Integer

' []でアクセスするとそのキーの要素が自動で作られます
m["りんご"] = 45
m["みかん"] = 32
m["ぶどう"] = 210
m["めろん"] = 10000
m["すいか"] = 300
m["いちご"] = 15
m["れもん"] = 14675

'キーと値の列挙はそれぞれ別のインデックス付きプロパティでアクセスします。
For i = 0 To m.Size - 1
    Print m.Keys(i);" ";m.Items(i)
Next

'findメソッドは要素のインデックスを返します
Print m.find("りんご")
Print m.find("みかん")
Print m.find("とまと") '無い場合-1を返します

Print m["れもん"]
Print m["ぶどう"]
Print m["きゃべつ"] '[]アクセスの場合、存在しないキーは読み取りでも自動で作られます

Copyright © 飴屋/菖蒲

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。