视频图像处理系列索引 || Arcgis/Engine/Server开发索引 || Web Map Gis开发索引 || jquery表格组件 JQGrid索引
WPF MVVM模式开发实现简明教程索引 || ArcGIS Runtime WPF(.net C#)开发简明教程索引

SDL鼠标事件

鼠标事件有这么多种,手柄的可以忽视,Sdl.SDL_KEYDOWN,Sdl.SDL_KEYUP,Sdl.SDL_MOUSEMOTION,Sdl.SDL_MOUSEBUTTONDOWN,Sdl.SDL_MOUSEBUTTONUP应该是常用的。

 

public enum EventTypes

    {

        /// <summary>

        /// No event

        /// </summary>

        None = Sdl.SDL_NOEVENT,

        /// <summary>

        /// Active event

        /// </summary>

        ActiveEvent = Sdl.SDL_ACTIVEEVENT,

        /// <summary>

        /// Key down event

        /// </summary>

        KeyDown = Sdl.SDL_KEYDOWN,

        /// <summary>

        /// Key up event

        /// </summary>

        KeyUp = Sdl.SDL_KEYUP,

        /// <summary>

        /// Mouse Motion event

        /// </summary>

        MouseMotion = Sdl.SDL_MOUSEMOTION,

        /// <summary>

        /// Mouse button down event

        /// </summary>

        MouseButtonDown = Sdl.SDL_MOUSEBUTTONDOWN,

        /// <summary>

        /// Mouse button up event

        /// </summary>

        MouseButtonUp = Sdl.SDL_MOUSEBUTTONUP,

        /// <summary>

        /// Joystick Axis motion event

        /// </summary>

        JoystickAxisMotion = Sdl.SDL_JOYAXISMOTION,

        /// <summary>

        /// Joystick ball motion event

        /// </summary>

        JoystickBallMotion = Sdl.SDL_JOYBALLMOTION,

        /// <summary>

        /// Joystick hat motion event

        /// </summary>

        JoystickHatMotion = Sdl.SDL_JOYHATMOTION,

        /// <summary>

        /// Joystick button down event

        /// </summary>

        JoystickButtonDown = Sdl.SDL_JOYBUTTONDOWN,

        /// <summary>

        /// joystick button up event

        /// </summary>

        JoystickButtonUp = Sdl.SDL_JOYBUTTONUP,

        /// <summary>

        /// Video resize event

        /// </summary>

        VideoResize = Sdl.SDL_VIDEORESIZE,

        /// <summary>

        /// Video expose event

        /// </summary>

        VideoExpose = Sdl.SDL_VIDEOEXPOSE,

        /// <summary>

        /// Quit event

        /// </summary>

        Quit = Sdl.SDL_QUIT,

        /// <summary>

        /// Window manager event

        /// </summary>

        WindowManagerEvent = Sdl.SDL_SYSWMEVENT,

        /// <summary>

        /// user-defined event

        /// </summary>

        UserEvent = Sdl.SDL_USEREVENT

    }

 

鼠标点击后的button:

public enum MouseButton

    {

        /// <summary>

        /// None

        /// </summary>

        None = 0,

        /// <summary>

        /// Primary button. Typically the left button

        /// </summary>

        PrimaryButton = Sdl.SDL_BUTTON_LEFT,

        /// <summary>

        /// Secondary button. typically the right button

        /// </summary>

        SecondaryButton = Sdl.SDL_BUTTON_RIGHT,

        /// <summary>

        /// Middle button

        /// </summary>

        MiddleButton = Sdl.SDL_BUTTON_MIDDLE,

        /// <summary>

        /// Wheel up

        /// </summary>

        WheelUp = Sdl.SDL_BUTTON_WHEELUP,

        /// <summary>

        /// Wheel down

        /// </summary>

        WheelDown = Sdl.SDL_BUTTON_WHEELDOWN

    }

 

 

常用的代码写法

while (!quit) //建立事件主循环

            {

                    while (Sdl.SDL_PollEvent(out ev) == 0)//从队列里取出事件

                    {

                        Sdl.SDL_WaitEvent(out ev); //必须等待

 

                        if (ev.type == Sdl.SDL_MOUSEBUTTONDOWN)

                        {

                            if (ev.button.button == Sdl.SDL_BUTTON_LEFT)

                            {

                                MouseDown(ev.button);

                            }

                            else

                                if (ev.button.button ==Sdl.SDL_BUTTON_RIGHT)

                                {

                                }

                        }

                        else

                            if (ev.type == Sdl.SDL_MOUSEMOTION)

                            {

                                MouseMove (ev.button);

                            }

                            else

                                if (ev.type == Sdl.SDL_MOUSEBUTTONUP)

                                {

                                    if (ev.button.button ==Sdl.SDL_BUTTON_LEFT)

                                    {

                                        MouseUp (ev.button);

                                    }

                                }

                                else

                                    if (ev.type ==Sdl.SDL_VIDEORESIZE)

                                    {

 

                                    }

                                    else

                                        if (ev.type ==Sdl.SDL_QUIT)

                                        {

                                            quit = true;

                                            break;

                                        }

                    }

                }

 

 

在处理SDL的事件有两种模式,一种是等待 SDL_WaitEvent,另一种是轮询SDL_PollEvent

目前,在网上可以查到的文章,大多数都使用了轮询,还有人指出等待有时会导致事件处理延迟。但是我在实际coding中,使用SDL_PollEvent,一运行就风扇不停的转,用top看了下,cpu占用到了99%。

实际上,使用wait已经足够,我不大清楚这种轮询机制在什么时候会用到。

 

以下是一个SDL_PollEvent的原型。分析一下这段程序:

while(quit!=1)这个循环中,如果没有发生任何事件,quit始终为0,那么在用户没有任何操作的情况下,这里会无限循环,直到event发生,进入了SDL_PollEvent的循环中。

这就导致了cpu占用率达到了100%. 因此,这种方法是不可取的。

在外层有循环时,SDL_PollEvent论询是不能用的。如果单独使用,用户无操作的时候,又无法进入处理事件的部分。实在不能明白它有什么用。

我考虑是不是这个应该用在非实时处理的时候,比如while(quit!=1)循环中嵌入一个sleep(1)之类。

void WaitKeyboard(SubWin sw){

    int quit = 0;

    SDL_Event event;

    KEYBOARDMODE kmode = COMMAND;

    while(quit!=1){

        //        printf ( "waiting for keyboard action\n" );

     while( SDL_PollEvent(&event)){

       

        printf ( "WaitKeyboard: caught keyboard %x\n", event.key.keysym.sym );

        switch (event.type){

            case SDL_KEYDOWN:

                printf ( "tracking keydown\n" );

                kmode = TrackKeyDown(sw, event.key.keysym.sym, kmode);

                break;

            case SDL_QUIT:

                printf("Stop !\n");

                quit = 1;

                break;

        }

          }

    }

    endSDL();

}

 

接下来是SDL_WaitEvent的原型

while(quit!=1)的循环中,由于SDL_WaitEvent语句,在用户未发生任何操作前,程序处于等待状态,不会进入下一次循环,这样就避免了cpu占用的问题。

这样的做法才是正确处理SDL事件的方法。

 

void WaitKeyboard(SubWin sw){

    int quit = 0;

    SDL_Event event;

    KEYBOARDMODE kmode = COMMAND;

    while(quit!=1){

        //        printf ( "waiting for keyboard action\n" );

        //        while( SDL_PollEvent(&event)){

        SDL_WaitEvent(&event);

        printf ( "WaitKeyboard: caught keyboard %x\n", event.key.keysym.sym );

        switch (event.type){

            case SDL_KEYDOWN:

                printf ( "tracking keydown\n" );

                kmode = TrackKeyDown(sw, event.key.keysym.sym, kmode);

                break;

            case SDL_QUIT:

                printf("stop !\n");

                quit = 1;

                break;

        }

    }

    endSDL();

}

 

http://blog.chinaunix.net/uid-26456800-id-3337795.html

posted @ 2016-04-26 09:48  jhlong  阅读(2054)  评论(0编辑  收藏  举报
海龙的博客 jhlong@cnblogs 版权所有© 转载请注明链接.有用请推荐一下
代码全部经过本人测试,但不保证复制粘贴就正常运行,更不保证能解决你的问题,请结合前后代码及描述理解后修改和使用