|
|
2016/4/17(Sun) 12:42:51|NO.75236
OSもどきを作っていて、OSのかっこいいデザインなどを教えて下さい!
現在はロード画面までしかできてませんorz
スクリプトも一緒に教えていただけると光栄です。
|
|
2016/4/17(Sun) 14:06:18|NO.75239
OSもどきとはいえど、どのくらい本物に似せるかで話が違ってきます。
質問に答えるためにも、どの程度本物に似せるのか教えてくれませんか?
|
|
2016/4/17(Sun) 15:20:39|NO.75240
かなりリアルに再現したいと思ってます。
言い方が失礼かもしれませんがそこらへんにあるOSもどきとは違って
マルチタスクにも対応していて、フルスクリーンモードで動作するものを作りたいです。
現在できているソースコード
#include"hspsock.as"
#include"Buffer.hsp"
title"Cylinder graphic user control interface"
buffer 1,1280,800:cls 4
bgscr 0,1280,800,0,0,0
gradf 0,0,1280,400,1,$000000,$0000BC
gradf 0,400,1280,400,1,$0000BC,$000000
setease 0,1280,ease_quad_out
i=0
repeat ; 画面をクリア
x = getease(i,60) ; イージング値の取得(整数)
color 0,0,50
boxf 0,200,X,600
wait 1
i=i+1
if X==1280:break
loop
pos 0,205:picload"Graphic/logo.png",1
color 200,200,200:font"Ubuntu":pos 10,280
mes"Cylinder graphic user control interface"
mes"(C) Cylinder corporation"
pos 550,275:picload"Graphic/user.png",1
font"Ubuntu",20
color 200,200,200:pos 570,486:mes"Welcome"
repeat rnd(10)
fileCMA=1
repeat 29
pos 590,420:picload"Animation/"+fileCMA+".png",1
wait 6
color 0,0,50:boxf 590,420,650,484
fileCMA+1
loop
picload"Animation/1.png",1
wait 6
loop
repeat 10
gmode 3,1280,800,100
pos 0,0:gcopy 1,0,0,1280,800
wait 5
loop
cls 4
wait 10
dmmplay 0,0
インクルードしている Buffer.hsp は読み込みなどを行っています。

| |
|
2016/4/17(Sun) 15:23:09|NO.75241
Buffer.hspを知りたいです。
|
|
2016/4/17(Sun) 15:24:42|NO.75242
;Buffer.hsp ソースコード
#include"hspogg.as"
dmmini
dmmload"Audio/boot.ogg",0,0
|
|
2016/4/17(Sun) 15:34:47|NO.75244
回答ありがとうございました!
OSもどきが出来次第、公開します!
|
|
2016/4/17(Sun) 15:44:28|NO.75245
マルチタスクを物凄く単純に作るなら、フラグで起動オンオフする位でしょうか。
process_みたいな配列を作ってタスク管理。
また、各アプリをサブルーチンで作っておく。
process_label()をラベル型変数とすることで、
process_の要素数分同じ数のアプリを起動(サブルーチン回る)することもできる。
同じアプリを起動するにあたって、競合も考えてアプリ(サブルーチン)を作らなければならない。
後は、process_winflg()で最小化や窓化,最大化を判定したりと
必要に応じて増やしていけばいい。
また、ウィンドウ表示用のモジュールを作っておいて、
process_winflg(添字)=1の時なら
各アプリ(サブルーチン)毎に保存されたセーブデータから
process_winx(表示サイズ)_winy()_posx(表示座標)_posy()_scalingflg(ズームon/offフラグ)などを取り出す。
スケーリングをするか、アプリ内の描写処理で対応するか、など。
モジュール変数で管理できれば楽なのかな……
|
|
2016/4/17(Sun) 19:03:32|NO.75254
SetParent使うのって邪道ですかね。
|
|
2016/4/18(Mon) 08:30:34|NO.75260
SetParentって何ですか?
一応googleで調べたんですけどよくわからないクソ長いスクリプトが出てきてわかりませんでした。
|
|
2016/4/19(Tue) 20:51:01|NO.75271
投稿遅れて申し訳ありませんでした。
あかささんとkanamaruさんが教えてくださったSetParentについてなんですが
kanamaruさんの貼ってくれたリンクに飛んで見るとなんとなく意味がわかったような気がしました!
|
|
2016/4/19(Tue) 20:58:14|NO.75272
いろいろ調べたんですけど、こういうのを改造したらいいんですか?
#uselib "user32"
#func SetParent "SetParent" int, int
ParentHwnd = hwnd
screen 1, 300,200, 0, 10,10
;ここに子ウィンドウで実行するスクリプトを入れる
SetParent hwnd, ParentHwnd
なんせ小6なんで...
|
|
2016/4/19(Tue) 20:58:52|NO.75273
小6でプログラミングってまだ早いですかね...
|
|
2016/4/21(Thu) 13:12:12|NO.75277
こういうのどうかな?
#module
#uselib "User32.dll"
#func DrawEdge "DrawEdge" int,int,int,int
#func DrawText "DrawTextA" int,int,int,int,int
#uselib "UxTheme.dll"
#cfunc OpenThemeData "OpenThemeData" int, wstr
#func DrawThemeBackground "DrawThemeBackground" int, int, int, int, int, int
#func CloseThemeData "CloseThemeData" int
//DrawWindowFrame ウィンドウを描画
//a1,p1,p2,p3,s1,p4,p5
//a1 RECT構造体
//p1 タイトルバーの高さ
//p2 枠の太さ
//p3 描画モード(0:UxTheme使用 1:オリジナルスタイル)
//s1 タイトルバーの文字
//p4 ウィンドウ内の描画領域に描画するウィンドウもしくはバッファID
//p5 アクティブウィンドウ(0)か非アクティブウィンドウ(1)か
//
//命令実行時に指定されているフォントが、タイトルバーの文字のフォントとなり、
//指定されている色は、背景色となります。
#deffunc DrawWindowFrame array a1,int p1,int p2,int p3,str s1,int p4,int p5
RECT=a1(0)+p2,a1(1)+p1,a1(2)-p2+1,a1(3)-p2+1
boxf RECT(0),RECT(1),RECT(2),RECT(3)
DrawEdge hdc,varptr(RECT),2|8,1|2|4|8
if p4!0:pos RECT(0)+2,RECT(1)+2:gcopy p4,0,0,RECT(2)-RECT(0)-4,RECT(3)-RECT(1)-4
if p3=0{
p=0:if p5:p=2
hTheme=OpenThemeData(hwnd,"Window")
//タイトルバー
RECT=a1(0),a1(1),a1(2),a1(1)+p1
DrawThemeBackground hTheme,hdc,1,p,varptr(RECT)
s=s1:RECT=a1(0)+5,a1(1),a1(2)-5,a1(1)+p1
syscolor 9
DrawText hdc,varptr(s),-1,varptr(RECT),32804
//ウィンドウの枠
RECT==a1(0),a1(1)+p1,a1(0)+p2,a1(3)
DrawThemeBackground hTheme,hdc,7,p,varptr(RECT)//左
RECT=a1(2)-p2,a1(1)+p1,a1(2),a1(3)
DrawThemeBackground hTheme,hdc,8,p,varptr(RECT)//右
RECT=a1(0),a1(3)-p2,a1(2),a1(3)
DrawThemeBackground hTheme,hdc,12,p,varptr(RECT)//下
CloseThemeData hTheme
}else:if p3=1{
//タイトルバー
if p5:color 0,0,128:else:color 0,0,255//タイトルバーの色
RECT=a1(0),a1(1),a1(2),a1(1)+p1
boxf RECT(0),RECT(1),RECT(2),RECT(3)
s=s1:RECT=a1(0)+5,a1(1),a1(2)-5,a1(1)+p1
color 255,255,255//タイトルバーの文字色
DrawText hdc,varptr(s),-1,varptr(RECT),32804
//ウィンドウの枠
if p5:color 0,0,128:else:color 0,0,255//ウィンドウの枠の色(左)
RECT==a1(0),a1(1)+p1,a1(0)+p2,a1(3)
boxf RECT(0),RECT(1),RECT(2),RECT(3)//左
if p5:color 0,0,128:else:color 0,0,255//ウィンドウの枠の色(右)
RECT=a1(2)-p2,a1(1)+p1,a1(2),a1(3)
boxf RECT(0),RECT(1),RECT(2),RECT(3)//右
if p5:color 0,0,128:else:color 0,0,255//ウィンドウの枠の色(下)
RECT=a1(0),a1(3)-p2,a1(2),a1(3)
boxf RECT(0),RECT(1),RECT(2),RECT(3)//下
}
return
#global
//上位ワード/下位ワード切り出しマクロ
#define ctype LOWORD(%1) (%1 & 0xFFFF)
#define ctype HIWORD(%1) (%1 >> 16 & 0xFFFF)
buffer 10//ウィンドウ内に表示する画像
font "MS Gothic",25,2
color 255,10,10
mes "仮想OS"
buffer 11//ウィンドウ内に表示する画像
font "MS Gothic",25,2
color 0,0,0:boxf
color 255,10,10
mes "仮想OS"
screen 0
//上位ワードにY座標、下位ワードにX座標
TitleBarY=30//タイトルバーの高さ
WindowPos=(0&0xFFFF)|(0<<16)//ウィンドウの位置
WindowSize=(200&0xFFFF)|(200<<16)//ウィンドウの大きさ
WindowTheme=0//ウィンドウテーマ(1にするとクラシック風)
ActiveWindow=0//アクティブウィンドウID
MaxWindow=1
objsize 100,30
button gosub "ウィンドウ追加",*AddWindow
button gosub "テーマ切り替え",*ChangeWindowTheme
gosub *DrawWindow
oncmd gosub *OnLButtonDown,0x0201
oncmd gosub *OnLButtonUp,0x0202
oncmd gosub *OnMouseMove,0x0200
stop
*OnLButtonDown
//アクティブウィンドウから処理を始める
WindowStartPos=mousex-LOWORD(WindowPos(ActiveWindow)),mousey-HIWORD(WindowPos(ActiveWindow))
x1=WindowStartPos(0)
y1=WindowStartPos(1)
x2=LOWORD(WindowSize(ActiveWindow))
if x1>=0 & y1>=0 & x1<=x2 & y1<=TitleBarY{
DropFlag=ActiveWindow+1
ActiveWindow=ActiveWindow
return
}
//非アクティブウィンドウ
repeat MaxWindow
WindowStartPos=mousex-LOWORD(WindowPos(cnt)),mousey-HIWORD(WindowPos(cnt))
x1=WindowStartPos(0)
y1=WindowStartPos(1)
x2=LOWORD(WindowSize(cnt))
if x1>=0 & y1>=0 & x1<=x2 & y1<=TitleBarY{
DropFlag=cnt+1
ActiveWindow=cnt
break
}
loop
return
*OnLButtonUp
DropFlag=0
return
*OnMouseMove
if DropFlag=0:return
WndID=DropFlag-1
WindowPos(WndID)=((mousex-WindowStartPos(0))&0xFFFF)|((mousey-WindowStartPos(1))<<16)
gosub *DrawWindow
redraw
return
*DrawWindow
redraw 0
color 255,255,255:boxf
repeat MaxWindow
//ウィンドウ情報取得
RECT(0)=LOWORD(WindowPos(cnt))
RECT(1)=HIWORD(WindowPos(cnt))
RECT(2)=LOWORD(WindowPos(cnt))+LOWORD(WindowSize(cnt))
RECT(3)=HIWORD(WindowPos(cnt))+HIWORD(WindowSize(cnt))
syscolor 15
font "Meiryo",12,1
DrawWindowFrame RECT,30,5,WindowTheme,"ウィンドウ "+cnt,11,1
loop
//アクティブウィンドウ処理
RECT(0)=LOWORD(WindowPos(ActiveWindow))
RECT(1)=HIWORD(WindowPos(ActiveWindow))
RECT(2)=LOWORD(WindowPos(ActiveWindow))+LOWORD(WindowSize(ActiveWindow))
RECT(3)=HIWORD(WindowPos(ActiveWindow))+HIWORD(WindowSize(ActiveWindow))
syscolor 15
font "Meiryo",12,1
DrawWindowFrame RECT,30,5,WindowTheme,"ウィンドウ "+ActiveWindow,11,0
redraw 1
return
*AddWindow
MaxWindow++
x+20
y+20
WindowPos(MaxWindow-1)=(x&0xFFFF)|(y<<16)//ウィンドウの位置
WindowSize(MaxWindow-1)=(200&0xFFFF)|(200<<16)//ウィンドウの大きさ
ActiveWindow=MaxWindow-1
gosub *DrawWindow
return
*ChangeWindowTheme
WindowTheme^1
gosub *DrawWindow
return

| |
|
2016/4/21(Thu) 16:41:15|NO.75278
InoueSoftwearさんに対抗して、OSもどき補助モジュール(?)
を作ってみました。
#module
#uselib "kernel32.dll"
#func CloseHandle "CloseHandle" int
#cfunc CreateMutex "CreateMutexA" int, int, sptr
#cfunc GetLastError "GetLastError"
#define ERROR_ALREADY_EXISTS 183
#define MUTEX_NAME "HSP_WinAPI_Test_Mutex"
#defcfunc AlreadyAppRunning
if (hMutex == 0) {
hMutex = CreateMutex(0, 0, MUTEX_NAME)
if (GetLastError() == ERROR_ALREADY_EXISTS) {
alreadyRunning = 1
} else {
alreadyRunning = 0
}
}
return alreadyRunning
#deffunc CleanupAppRunChecker onexit
if (hMutex != 0) {
CloseHandle hMutex
hMutex = 0
}
return
#global
#module
#uselib "user32"
#defcfunc gethwnd int i
nowid = ginfo(3)
gsel i
ret = hwnd
gsel nowid
return ret
#func SetParent "SetParent" int, int
#deffunc setchild int hnd
SetParent gethwnd(hnd), gethwnd(0)
return
#deffunc screen2 int id,int x,int y,int type,int x2,int y2,int x3,int y3
screen id,x,y,type,x2,y2,x3,y3
setchild id
return
#global
#undef screen
#define screen(%1=0,%2=640,%3=480,%4=0,%5=-1,%6=-1,%7=ginfo_sx,%8=ginfo_sy) screen2 %1,%2,%3,%4,%5,%6,%7,%8:oncmd *virtual_os_saisyouka,0x5
if (AlreadyAppRunning()) {
end
}
onexit gosub *virtual_os_exit
bgscr 0,ginfo(20),ginfo(21),,0,0
//ここにソースを好きに入れる。sdreen命令でID0以外は自動dせ子ウィンドウになります。
screen 1
stop
*virtual_os_exit
if(ginfo_act=0):end
gsel ginfo_act,-1
return
*virtual_os_saisyouka
if(wparam=1){
gsel ginfo_act,-1
//ここに独自タスクバーへの格納処理を入れる。ginfo_actに最小化したウィンドウIDが入っています。
}

| |
|
2016/4/21(Thu) 16:44:13|NO.75279
訂正で、一個目にコメントのsdreenはscreenで、
その次の行のscreen 1は消してください(testソースが残ってました。)
|
|
2016/4/22(Fri) 21:50:31|NO.75294
OSもどきだとサブルーチンかオブジェクトライクなコードのほうが作りやすいと思われ
|
|
2016/4/24(Sun) 12:02:27|NO.75303
返信遅れてすいません
とりあえず今、できている機能は
・オーディオプレーヤー
・画像ビューア
・テキストエディタ
OSもどきの機能
・マルチタスクのウィンドウ(SetParent)
・スタートボタン
ここでまた質問なんですけどデスクトップのアイコン(マイコンピュータとか)
を作ったんですけど移動させたりダブルクリック判定させるのはどうすればいいでしょうか...
bgscr 0,1280,800,0,0,0
*draw
gradf 0,0,1280,400,1,$000000,$0000BC
gradf 0,400,1280,400,1,$0000BC,$000000
color 0,0,0:boxf X,Y,X+30,Y+30
onclick *move
stop
*move
repeat
color 255,255,255:boxf X,Y,X+30,Y+30
X=mouseX
Y=mouseY
color 0,0,0:boxf X,Y,X+30,Y+30
wait 1
getkey left,1
if left==0 :break
loop
goto*draw
一応、作ってみたんですけど移動させた時に背景がboxf命令で潰されてしまうので
何かいい策ありますかねぇ...
|
|
2016/4/24(Sun) 15:21:00|NO.75306
こういう感じかな?
機能
■右クリックでアイコン追加します。
(要らなければ、[if wparam=2:gosub *dsktpiconAdd]を消すとOK)
■ドラッグ時の半透明画像も表示できるようにした。
■アイコンの名前を表示できるようにした。
■ダブルクリック時のアイコンID判定もできるようにした。
(アイコン9をダブルクリックすると終了する。要らなければ、[if index=9:end]を消すとOK)
■全画面で表示できるようにした。
#include "user32.as"
#define ctype InCursor(%1,%2,%3,%4,%5,%6) %1>=%3 & %2>=%4 & %1<=%5 & %2<=%6
//上位ワード/下位ワード切り出しマクロ
#define ctype LOWORD(%1) (%1 & 0xFFFF)
#define ctype HIWORD(%1) (%1 >> 16 & 0xFFFF)
#define ctype LHWRITE(%1,%2) (%1&0xFFFF)|(%2<<16)
IconSX=32:IconSY=32//アイコンの大きさ
ScreenSX=ginfo(20):ScreenSY=ginfo(21)//スクリーンの大きさ
//上位ワードにY座標、下位ワードにX座標
dim IconPos,0//アイコンの位置
sdim IconName,,0//アイコンの名前
dim IconMax,0//アイコンの個数
dim IconImageID,0//アイコンの画像ID
bgscr 0,ScreenSX,ScreenSY,0,0,0
GetClassLong hwnd, -26
SetClassLong hwnd, -26, stat | 0x8//ダブルクリックイベントを受け取れる様にウィンドウクラスをいじる。
onclick *move//クリックイベント
oncmd gosub *dblclk,0x0203//ダブルクリックイベント
repeat 10//とりあえず9個アイコンを付ける
gosub *dsktpiconAdd
loop
stop
*move//クリックイベント
if wparam=1{
index=-1
repeat IconMax
X=LOWORD(IconPos(cnt))
Y=HIWORD(IconPos(cnt))
if InCursor(mousex,mousey,X,Y,X+IconSX,Y+IconSY){
index=cnt
}
loop
if index!-1{
_X=LOWORD(IconPos(index))
_Y=HIWORD(IconPos(index))
__X=mousex-_X
__Y=mousey-_Y
repeat
redraw 0//ちらつきをなくす
MX=mouseX-__X
MY=mouseY-__Y
if MX<0:MX=0
if MY<0:MY=0
if MX+IconSY>ScreenSX:MX=ScreenSX-IconSY
if MY+IconSY>ScreenSY:MY=ScreenSY-IconSY
gosub *dsktp
gosub *dsktpicon
gmode 3,IconSX,IconSY,128
//ドラッグ中のアイコン描画
pos MX,MY:gcopy IconImageID(index)
RECT=MX-10,MY+IconSY,MX+IconSX+10,MY+IconSY+14
s=IconName(index)
sysfont 17:color 255,255,255
DrawText hdc,varptr(s),-1,varptr(RECT),32809
redraw 1
wait 1
getkey left,1
if left==0 :break
loop
gosub *dsktp
IconPos(index)=LHWRITE(MX,MY)//アイコンの位置
gosub *dsktpicon
redraw
}
}
if wparam=2:gosub *dsktpiconAdd
stop
*dblclk//ダブルクリックイベント
if wparam=1{
index=-1
repeat IconMax
X=LOWORD(IconPos(cnt))
Y=HIWORD(IconPos(cnt))
if InCursor(mousex,mousey,X,Y,X+IconSX,Y+IconSY){
index=cnt
}
loop
dialog "index="+index
if index=9:end//9番のアイコンを押すと終了
}
return
*dsktp
gsel 0
gradf 0,0,ScreenSX,ScreenSY/2,1,$000000,$0000BC
gradf 0,ScreenSY/2,ScreenSX,ScreenSY/2,1,$0000BC,$000000
return
*dsktpicon
gsel 0
repeat IconMax
X=LOWORD(IconPos(cnt))
Y=HIWORD(IconPos(cnt))
gmode 0,IconSX,IconSY,256
pos X,Y:gcopy IconImageID(cnt)
RECT=X-10,Y+IconSY,X+IconSX+10,Y+IconSY+14
s=IconName(cnt)
sysfont 17:color 255,255,255
DrawText hdc,varptr(s),-1,varptr(RECT),32809
loop
return
*dsktpiconAdd
buffer 10+IconMax,IconSX,IconSY//アイコンの画像を作成
color 255,255,255:boxf
color 0,0,0:font "MS Gothic",IconSY
RECT=0,0,IconSX,IconSY:s=""+IconMax
DrawText hdc,varptr(s),-1,varptr(RECT),32805//とりあえず番号を表示
gsel 0
//アイコンの情報を設定
IconPos(IconMax)=LHWRITE(10,IconMax*IconSY+(16*IconMax)+10)//アイコンの位置
IconName(IconMax)="Icon"+strf("(%d)",IconMax)//アイコンの名前
IconImageID(IconMax)=10+IconMax//アイコンの画像ID
IconMax++//アイコンの個数を1増やす
//描画
gosub *dsktp
gosub *dsktpicon
redraw
return

| |
|
2016/4/24(Sun) 15:45:57|NO.75307
ありがとうございました!!!
思ってたよりかなり理想に近いです!!!(いや、理想以上かな?)
|
|
2016/4/24(Sun) 16:11:20|NO.75308
いろいろ改造してみたんですけど
とあるページの右クリックメニューの項目をみて
「(゚∀゚)KOREDA!!!」とおもって"作成"項目と"削除"項目をつけてみたんですけどなぜか
"削除"を押しても無反応なんです。
改善策を教えていただけると光栄です。無知ですいません。
#include "user32.as"
#define ctype InCursor(%1,%2,%3,%4,%5,%6) %1>=%3 & %2>=%4 & %1<=%5 & %2<=%6
//上位ワード/下位ワード切り出しマクロ
#define ctype LOWORD(%1) (%1 & 0xFFFF)
#define ctype HIWORD(%1) (%1 >> 16 & 0xFFFF)
#define ctype LHWRITE(%1,%2) (%1&0xFFFF)|(%2<<16)
// ポップアップメニューの表示サンプルソース (by Kpan)
// (注) エディタの[HSP]メニュー→[HSP拡張マクロを使用する]を要有効。
; 項目ID
#enum IDM_ITEM1 = 1
#enum IDM_ITEM2
#enum IDM_ITEM3
#enum IDM_ITEM4
; マウスをクリックした時
; あるいはWM_CONTEXTMENU
; oncmd gosub *onjump, $7B
onexit *exit
; <サブのポップアップメニュー>
; サブメニューを作成し、ハンドルを取得
CreatePopupMenu
hMenu.0 = stat
; <メインのポップアップメニュー>
; メインのポップアップメニューを作成し、ハンドルを取得
CreatePopupMenu
hMenu.1 = stat
AppendMenu hMenu.1, 0, IDM_ITEM1, "作成"
; 第2パラを$800にするとセパレータ(区切り線)になる。
AppendMenu hMenu.1, 0, IDM_ITEM2, "削除"
; 第2パラメータを$10にするとサブメニューへ。
goto*stt
*exit
; どこのウィンドウにも張り付いていないメニューは明示的に破棄
DestroyMenu hMenu.1
end
*stt
IconSX=32:IconSY=32//アイコンの大きさ
ScreenSX=ginfo(20):ScreenSY=ginfo(21)//スクリーンの大きさ
//上位ワードにY座標、下位ワードにX座標
dim IconPos,0//アイコンの位置
sdim IconName,,0//アイコンの名前
dim IconMax,0//アイコンの個数
dim IconImageID,0//アイコンの画像ID
bgscr 0,ScreenSX,ScreenSY,0,0,0
GetClassLong hwnd, -26
SetClassLong hwnd, -26, stat | 0x8//ダブルクリックイベントを受け取れる様にウィンドウクラスをいじる。
onclick gosub*move//クリックイベント
oncmd gosub *dblclk,0x0203//ダブルクリックイベント
repeat 10//とりあえず9個アイコンを付ける
gosub *dsktpiconAdd
loop
stop
*move//クリックイベント
if wparam=1{
index=-1
repeat IconMax
X=LOWORD(IconPos(cnt))
Y=HIWORD(IconPos(cnt))
if InCursor(mousex,mousey,X,Y,X+IconSX,Y+IconSY){
index=cnt
}
loop
if index!-1{
_X=LOWORD(IconPos(index))
_Y=HIWORD(IconPos(index))
__X=mousex-_X
__Y=mousey-_Y
repeat
redraw 0//ちらつきをなくす
MX=mouseX-__X
MY=mouseY-__Y
if MX<0:MX=0
if MY<0:MY=0
if MX+IconSY>ScreenSX:MX=ScreenSX-IconSY
if MY+IconSY>ScreenSY:MY=ScreenSY-IconSY
gosub *dsktp
gosub *dsktpicon
gmode 3,IconSX,IconSY,128
//ドラッグ中のアイコン描画
pos MX,MY:gcopy IconImageID(index)
RECT=MX-10,MY+IconSY,MX+IconSX+10,MY+IconSY+14
s=IconName(index)
sysfont 17:color 255,255,255
DrawText hdc,varptr(s),-1,varptr(RECT),32809
redraw 1
wait 1
getkey left,1
if left==0 :break
loop
gosub *dsktp
IconPos(index)=LHWRITE(MX,MY)//アイコンの位置
gosub *dsktpicon
redraw
}
}
if wparam = 2 {
; ポップアップメニュー表示。第1パラに開くメニューのハンドル
TrackPopupMenu hMenu.1, $100, ginfo(0), ginfo(1), 0, hwnd, 0
if stat = 0 : return ; 選択キャンセル
; statにメニュー項目ID
if stat==1 :gosub*dsktpiconAdd
if stat==2 :gosub*dsktpicondlt
return
}
return
stop
*dblclk//ダブルクリックイベント
if wparam=1{
index=-1
repeat IconMax
X=LOWORD(IconPos(cnt))
Y=HIWORD(IconPos(cnt))
if InCursor(mousex,mousey,X,Y,X+IconSX,Y+IconSY){
index=cnt
}
loop
if index==-1 :return
dialog "index="+index
if index==9:end//9番のアイコンを押すと終了
}
return
*dsktp
gsel 0
gradf 0,0,ScreenSX,ScreenSY/2,1,$000000,$0000BC
gradf 0,ScreenSY/2,ScreenSX,ScreenSY/2,1,$0000BC,$000000
return
*dsktpicon
gsel 0
repeat IconMax
X=LOWORD(IconPos(cnt))
Y=HIWORD(IconPos(cnt))
gmode 0,IconSX,IconSY,256
pos X,Y:gcopy IconImageID(cnt)
RECT=X-10,Y+IconSY,X+IconSX+10,Y+IconSY+14
s=IconName(cnt)
sysfont 17:color 255,255,255
DrawText hdc,varptr(s),-1,varptr(RECT),32809
loop
return
*dsktpiconAdd
buffer 10+IconMax,IconSX,IconSY//アイコンの画像を作成
color 255,255,255:boxf
color 0,0,0:font "MS Gothic",IconSY
RECT=0,0,IconSX,IconSY:s=""+IconMax
DrawText hdc,varptr(s),-1,varptr(RECT),32805//とりあえず番号を表示
gsel 0
//アイコンの情報を設定
IconPos(IconMax)=LHWRITE(10,IconMax*IconSY+(16*IconMax)+10)//アイコンの位置
IconName(IconMax)="Icon"+strf("(%d)",IconMax)//アイコンの名前
IconImageID(IconMax)=10+IconMax//アイコンの画像ID
IconMax++//アイコンの個数を1増やす
//描画
gosub *dsktp
gosub *dsktpicon
redraw
return
*dsktpicondlt
iconmax-1
index=-1
repeat IconMax
X=LOWORD(IconPos(cnt))
Y=HIWORD(IconPos(cnt))
if InCursor(mousex,mousey,X,Y,X+IconSX,Y+IconSY){
index=cnt
}
loop
if index==-1 :return
indexmax-1
gosub *dsktp
gosub *dsktpicon
redraw 1
return

| |
|
2016/4/25(Mon) 12:32:40|NO.75314
こんな感じですかね。
削除の仕組みは、スクリプトを見ていただくとわかると思います。
あと、メニューはサンプルからコピペしたのだと思いますが、
ラベルの位置は、一番最後に貼り付けても問題ありません。(ラベル *exit)
(途中に突っ込むと、訳が分からなくなる場合があります。)
機能
■アイコンの背景部分を透明にする事が可能
■ほかのウィンドウを仮想OS画面に埋め込む事が可能(SetParent_VOS命令)
■削除が可能
■アイコンの上にカーソルが乗った状態か否かで、メニューを切り替えることが可能
あとは、工夫次第で良い感じになると思います。
#include "user32.as"
#include "shell32.as"
#define ctype InCursor(%1,%2,%3,%4,%5,%6) %1>=%3 & %2>=%4 & %1<=%5 & %2<=%6
//上位ワード/下位ワード切り出しマクロ
#define ctype LOWORD(%1) (%1 & 0xFFFF)
#define ctype HIWORD(%1) (%1 >> 16 & 0xFFFF)
#define ctype LHWRITE(%1,%2) (%1&0xFFFF)|(%2<<16)
// ポップアップメニューの表示サンプルソース (by Kpan)
// (注) エディタの[HSP]メニュー→[HSP拡張マクロを使用する]を要有効。
//項目ID
#enum IDM_DIADD = 100
#enum IDM_DIDEL
//コンテキストメニュー作成
onexit *exit//終了時に*exitへ飛ぶようにする。
CreatePopupMenu//アイコンがホット状態であるメニュー
hMenu.2 = stat
AppendMenu hMenu.2, 0, IDM_DIADD, "作成"
AppendMenu hMenu.2, 0, IDM_DIDEL, "削除"
CreatePopupMenu//アイコンがホット状態でないメニュー
hMenu.1 = stat
AppendMenu hMenu.1, 0, IDM_DIADD, "作成"
//親メニューを作り、メニューをまとめて終了時に削除する
//(親を削除すると、子も自動的に削除される機能を応用)
CreatePopupMenu
hMenu.0 = stat
AppendMenu hMenu.0, 0x10, hMenu.1, ""
AppendMenu hMenu.0, 0x10, hMenu.2, ""
IconSX=32:IconSY=32//アイコンの大きさ
ScreenSX=ginfo(20):ScreenSY=ginfo(21)//スクリーンの大きさ
buffer 5//ファイルのアイコン1
color 255,0,255:boxf//桃色は透明色
//ここにアイコンを描画する命令を書き込む
//とりあえずシステムのアイコンを描画
//▼▼▼
filename = "SHELL32.dll":hIcon=0:IconIndex=12//シェルから取り出す
ExtractIconEx varptr(filename),IconIndex,varptr(hIcon),0,1
DrawIconEx hdc,0,0,hIcon,IconSX,IconSY,0,0,3//アイコン描画
DestroyIcon hIcon
//▲▲▲
buffer 6//ファイルのアイコン2
color 255,0,255:boxf//桃色は透明色
//ここにアイコンを描画する命令を書き込む
//とりあえずシステムのアイコンを描画
//▼▼▼
filename = "SHELL32.dll":hIcon=0:IconIndex=27//シェルから取り出す
ExtractIconEx varptr(filename),IconIndex,varptr(hIcon),0,1
DrawIconEx hdc,0,0,hIcon,IconSX,IconSY,0,0,3//アイコン描画
DestroyIcon hIcon
//▲▲▲
//アイコン情報変数初期化
//上位ワードにY座標、下位ワードにX座標
dim IconPos,0//アイコンの位置
sdim IconName,,0//アイコンの名前
dim IconMax,0//アイコンの個数
dim IconImageID,0//アイコンの画像ID
dim IconOID,0
//仮想OSデスクトップ画面
bgscr 0,ScreenSX,ScreenSY,2,0,0
title ""
GetClassLong hwnd, -26
SetClassLong hwnd, -26, stat | 0x8//ダブルクリックイベントを受け取れる様にウィンドウクラスをいじる。
GetWindowLong hwnd, -20
SetWindowLong hwnd, -20,stat | 0x80
onclick gosub*move//クリックイベント
oncmd gosub *dblclk,0x0203//ダブルクリックイベント
gsel 0,1
PdsktpiconAdd "見知らぬファイル.txt",5,-1,100//アイコン追加
PdsktpiconAdd "メモ帳",5,-1,101//アイコン追加
PdsktpiconAdd "終了",6,-1,102//アイコン追加
stop
*move//クリックイベント
if wparam=1{
index=GetHotIconIndex()
if index!-1{
_X=LOWORD(IconPos(index))
_Y=HIWORD(IconPos(index))
__X=ginfo(0)-ginfo(4)-_X
__Y=ginfo(1)-ginfo(5)-_Y
repeat
redraw 0//ちらつきをなくす
MX=ginfo(0)-ginfo(4)-__X
MY=ginfo(1)-ginfo(5)-__Y
if MX<0:MX=0
if MY<0:MY=0
if MX+IconSY>ScreenSX:MX=ScreenSX-IconSY
if MY+IconSY>ScreenSY:MY=ScreenSY-IconSY
gosub *dsktp
gosub *dsktpicon
gmode 4,IconSX,IconSY,128
//ドラッグ中のアイコン描画
color 255,0,255//桃色を透明色にする
pos MX,MY:gcopy IconImageID(index)
RECT=MX-10,MY+IconSY,MX+IconSX+10,MY+IconSY+(14*2)
s=IconName(index)
sysfont 17:color 255,255,255
DrawText hdc,varptr(s),-1,varptr(RECT),40985
redraw 1
wait 1
getkey left,1
if left==0 :break
loop
gosub *dsktp
IconPos(index)=LHWRITE(MX,MY)//アイコンの位置
gosub *dsktpicon
redraw
}
}
if wparam = 2 {
p=hMenu.2
index=GetHotIconIndex()
if index=-1:p=hMenu.1//デスクトップの背景で右クリック
TrackPopupMenu p, $100, ginfo(0), ginfo(1), 0, hwnd, 0//ポップアップメニュー表示
if stat = 0 : return
//wIDにメニュー項目ID
wID=stat
if wID=IDM_DIADD :goto *dsktpiconAdd
if wID=IDM_DIDEL :Pdsktpicondlt index:goto *rf_dsktp
return
}
return
stop
*dblclk//ダブルクリックイベント
if wparam=1{
index=GetHotIconIndex()
if index==-1 :return
id=GetIconIndexToID(index)
//indexにアイコンインデックス
//idにアイコンID
if id==100{
if IconName(index)!"知っているファイル.txt"{
IconName(index)="知っているファイル.txt"//アイコン名変更
gosub *rf_dsktp
dialog "\"見知らぬファイル.txt\"を\"知っているファイル.txt\"に変更しました。"
}else:dialog "\"知っているファイル.txt\"に変更されています。"
return
}
if id==101{
gsel 0
exec "notepad"
SetParent_VOS "Notepad","無題 - メモ帳"//ウィンドウを自分のものにする
return
}
if id==102:goto *exit//idが102だった時に終了する
}
return
*rf_dsktp////デスクトップとアイコン描画
gosub *dsktp
gosub *dsktpicon
redraw
return
*dsktp//デスクトップ描画
gsel 0
gradf 0,0,ScreenSX,ScreenSY/2,1,$000000,$0000BC
gradf 0,ScreenSY/2,ScreenSX,ScreenSY/2,1,$0000BC,$000000
return
*dsktpicon//デスクトップアイコン描画
gsel 0
repeat IconMax
if IconImageID(cnt)!-1{//-1以外を処理(-1は「削除済みだよ」のID)
X=LOWORD(IconPos(cnt))
Y=HIWORD(IconPos(cnt))
gmode 4,IconSX,IconSY,256
color 255,0,255//桃色を透明色にする
pos X,Y:gcopy IconImageID(cnt)
RECT=X-10,Y+IconSY,X+IconSX+10,Y+IconSY+(14*2)
s=IconName(cnt)
sysfont 17:color 255,255,255
DrawText hdc,varptr(s),-1,varptr(RECT),40985
}
loop
return
*dsktpiconAdd//デスクトップアイコン追加
buffer 10+IconMax,IconSX,IconSY//アイコンの画像を作成
color 255,255,255:boxf
color 0,0,0:font "MS Gothic",IconSY
RECT=0,0,IconSX,IconSY:s=""+IconMax
DrawText hdc,varptr(s),-1,varptr(RECT),32805//とりあえず番号を表示
PdsktpiconAdd "Icon"+strf("(%d)",IconMax),10+IconMax,-1//アイコン追加
return
#deffunc PdsktpiconAdd str s1,int p1,int p2,int p3//デスクトップアイコン追加命令
//s1 = アイコンの名前
//p1 = アイコンの画像ID
//p2 = アイコンの位置(下位ワードにX座標、上位ワードにY座標)
// -1で自動設定
//p3 = オリジナルID(自由に設定できる)
gsel 0
//アイコンの情報を設定
if p2=-1:IconPos(IconMax)=LHWRITE(10,IconMax*IconSY+((16*2)*IconMax)+10)//アイコンの位置
if p2!-1:IconPos(IconMax)=p2
IconName(IconMax)=s1//アイコンの名前
IconImageID(IconMax)=p1//アイコンの画像ID
IconOID(IconMax)=p3//アイコンのオリジナルID
IconMax++//アイコンの個数を1増やす
//描画
gosub *dsktp
gosub *dsktpicon
redraw
return
#deffunc Pdsktpicondlt int p1//デスクトップアイコン削除命令
//p1 = アイコンID(-1を指定するとカーソル下にあるアイコンを削除)
_index=p1
if p1=-1{
_index=GetHotIconIndex()
if _index=-1:return 1
}
IconImageID(_index)=-1//アイコンを消す
return 0
#defcfunc GetHotIconIndex//デスクトップアイコンインデックス取得関数
a=ginfo(3)
gsel 0
_index=-1
repeat IconMax
X=LOWORD(IconPos(cnt))
Y=HIWORD(IconPos(cnt))
MX=ginfo(0)-ginfo(4)
MY=ginfo(1)-ginfo(5)
if InCursor(MX,MY,X,Y,X+IconSX,Y+IconSY+(14*2)){
if IconImageID(cnt)!-1:_index=cnt
}
loop
gsel a
return _index
#defcfunc GetIconIndexToID int p1//インデックスからIDを取得
return IconOID(p1)
#deffunc SetParent_VOS str s1,str s2
//ウィンドウを自分のものにする
//s1 = ウィンドウクラス
//s2 = ウィンドウタイトル
a=ginfo(3)
gsel 0
FindWindow s1,s2:_hwnd=stat
SetParent _hwnd,hwnd
SetWindowLong _hwnd,-8,hwnd
gsel a
return
*exit//終了処理
DestroyMenu hMenu.0//親メニューを削除
end

| |
|