Project1

标题: 禁止窗体移动 + EXIT动画 [打印本页]

作者: hide秀    时间: 2009-6-7 20:52
标题: 禁止窗体移动 + EXIT动画
1.禁止窗体移动
  禁止RM窗口的移动 当鼠标拖动RM窗口后 又会设置回原来的位置
  思路: 1.用Win32API 函数 getWindowRect 获取原来的窗口位置
        2.窗口消息处理 (需要夏娜的RmWndProc支持)
        3.接受到 WM_MOVE 消息后 设置窗口位置(原来的位置)
2.Exit动画
  就是按窗口右上角那个x关闭按钮 就会播放一段exit动画
  原理很简单 具体见脚本 可以根据需要制定自己的游戏的exit动画

范例下载:
http://rpg.blue/upload_program/d ... ��体_124808674.rar

脚本
1.RmWin 部分
class RmWin
  attr_accessor :left,:top,:right,:bottom
  attr_accessor :hwnd
  def initialize
    @left = 0
    @top = 0
    @right = 0
    @bottom = 0
    @hwnd = 0
  end  
end  


$rmWin = RmWin.new
window_Rect = Win32API.new("user32","GetWindowRect","lp","l")

val = "\0"*256
gps = Win32API.new("kernel32", "GetPrivateProfileString",%w(p p p p l p), "l")
gps.call("Game", "Title", "", val, 256, ".\\Game.ini")
val.delete!("\0")
   
fw = Win32API.new("user32", "FindWindow", %(p, p), "i")
$rmWin.hwnd = fw.call("RGSS Player", val)

pos = "\0"*16
result = window_Rect.call($rmWin.hwnd,pos)
if result != 0
  rect = pos.unpack("C*")
end

$wndmove = false
posLeft,posTop,posRight,posBottom = 0,4,8,12
$rmWin.left    = rect[posLeft+1]   * 0xFF + rect[posLeft]
$rmWin.top     = rect[posTop+1]    * 0xFF + rect[posTop]
$rmWin.right   = rect[posRight+1]  * 0xFF + rect[posRight]
$rmWin.bottom  = rect[posBottom+1] * 0xFF + rect[posBottom]

2.Graphics 和 Kernel 函数修改部分
module Graphics
  @ori = method("update") if @ori.nil?
  @swp = Win32API.new("user32", "SetWindowPos", %(l, l, i, i, i, i, i),"'i")
  def self.update(*args)
    @ori.call(*args)
    if $wndmove
      left = $rmWin.left
      top  = $rmWin.top
      @swp.call($rmWin.hwnd, -1, left, top,  640, 480, 1)
      $wndmove = false
    end  
  end  
end  

module Kernel
  alias ori_exit exit unless method_defined? :exit
  def exit(*args)
    Graphics.freeze
    Graphics.transition(20)
    @sp = Sprite.new
    @sp.x,@sp.y,@sp.z = 0,0,999999999
    @sp.bitmap = Bitmap.new(640,480)
    count = 0
    size = 6
    begin
      count += 1
      size += 1
      @sp.bitmap.clear
      @sp.bitmap.fill_rect(0,0,640,480,Color.new(0,0,0,255))
      @sp.bitmap.font.size = size
      @sp.bitmap.draw_text(0,200,640,100,"Thank You For Your Play",1)
      Graphics.update
    end until count == 40
    20.times{Graphics.update}
    ori_exit(*args)
  end  
end  

3.RmWndProc部分
#==============================================================================
# ■ RmWndProc
#------------------------------------------------------------------------------
#  处理RM窗口过程的模块。
#
#   v1.1
#
#   by 灼眼的夏娜
#
#   ※ 这个模块名以及该模块中的方法名字请勿更改!!!
#==============================================================================

module RmWndProc
  #--------------------------------------------------------------------------
  # ● API函数声明
  #--------------------------------------------------------------------------
  Replace = Win32API.new("Lib/RmWndProc","_replace","v","i")
  Restore = Win32API.new("Lib/RmWndProc","_restore","v","v")
  #--------------------------------------------------------------------------
  # ● 窗口过程函数 ※ 该名字切勿更改
  #--------------------------------------------------------------------------
  def self.wnd_proc(hwnd,msg,wparam,lparam)
    # 消息分歧
    case msg
    when 0x0003
      $wndmove = true
      return
    end
    # 调用默认窗口过程
    self.default_proc
  end
  #--------------------------------------------------------------------------
  # ● 转换窗口到RM脚本中进行处理
  #--------------------------------------------------------------------------
  def self.replace
    Replace.call
  end
  #--------------------------------------------------------------------------
  # ● 还原窗口过程
  #--------------------------------------------------------------------------
  def self.restore
    Restore.call
  end
  #--------------------------------------------------------------------------
  # ● 默认窗口过程 ※ 对于没有进行处理的消息我们在最后调用该方法来调用默认窗
  #                    口过程。
  #--------------------------------------------------------------------------
  def self.default_proc
    raise "default_proc"
  end
end

RmWndProc.replace




作者: 尤莉斯    时间: 2009-6-7 20:59
{/hx}偶是来做沙发的。。
作者: 越前リョーマ    时间: 2009-6-7 21:00
Exit还有动画……
真华丽了……
作者: tommay    时间: 2009-6-7 21:01
这么一来,退出游戏可以不用“$scene = nil”了{/dy}

强势收下了{/qiang}
作者: 小lim    时间: 2009-6-7 21:01
提示: 作者被禁止或删除 内容自动屏蔽
作者: 紫苏    时间: 2009-6-7 21:24
第一个应该可以直接屏蔽 WM_NCLBUTTONDOWN 吧,消息循环如果 wParam == HTCAPTION 就直接返回 HTNOWHERE~
  #--------------------------------------------------------------------------
  # ● 窗口过程函数 ※ 该名字切勿更改
  #--------------------------------------------------------------------------
  def self.wnd_proc(hwnd,msg,wparam,lparam)
    # 消息分歧
    case msg
    when 0x00A1
      return 0 if wparam == 2
    end
    # 调用默认窗口过程
    self.default_proc
  end

作者: 一路一风尘    时间: 2009-6-7 21:29
提示: 作者被禁止或删除 内容自动屏蔽
作者: 小lim    时间: 2009-6-7 21:36
提示: 作者被禁止或删除 内容自动屏蔽
作者: 紫苏    时间: 2009-6-7 21:38
以下引用一路一风尘于2009-6-7 13:29:01的发言:

呵呵,移动与鼠标点击都算消息,应都可拦截。

嗯,只不过 WM_MOVE 是左键弹起后才发送的,所以玩家还是可以按下左键拖拽窗口~~

刚测试了下,在系统菜单里面用移动,光屏蔽左键就不行了 =w=
看来还是要加上秀秀的方法,或者屏蔽系统菜单里面的移动
作者: 一路一风尘    时间: 2009-6-7 21:44
提示: 作者被禁止或删除 内容自动屏蔽
作者: 一路一风尘    时间: 2009-6-7 21:48
提示: 作者被禁止或删除 内容自动屏蔽
作者: 偶尔杀人越货    时间: 2009-6-7 21:49
让窗口不懂?? 有点“搞破坏”的感觉{/gg}
作者: hide秀    时间: 2009-6-7 22:00
when 0x84
return 1

可以真正禁止移动 不过标题栏所有操作都禁止掉了(包括最小化,关闭)
作者: 紫苏    时间: 2009-6-7 22:18
以下引用一路一风尘于2009-6-7 13:48:06的发言:

WM_MOVE应可以直接吃掉?

吃掉也没意义,因为这个和 WM_MOVING 一样是通知消息,是干完事了才发过来的马后炮{/cy}

用上面那个判断非客户区左键单击在标题栏的方式(最大最小退出的按钮还是可以响应的),再调用 GetSystemMenu 和 EnableMenuItem 禁止系统菜单里面的移动,玩家就彻底没法移动窗口了
作者: DeathKing    时间: 2009-6-7 23:44
不错DownLoad下来看看




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1