蓝森林首页 | 返回主页 | 本站地图 | 站内搜索 | 联系信箱 |
 您目前的位置:首页 > 自由软件 > 技术交流 > 应用编程


    

蓝森林 http://www.lslnet.com 2006年6月6日 10:18


>>>> 鼠标编程的尝试和疑问

:)


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
很高兴看到楼上的朋友的贴, 我遇到的问题和他竞如此相似.
在文本方式下显示鼠标后, 我尝试在图形方式下采用同样的方式显示鼠标, 结果失败, 于是我用了一个笨

的方法, 用画图函数画出了鼠标. 但我觉得这个方法太原始了, 想尝试更高级的鼠标显示方法, 看了一些

书, 有本书上用到了什么屏幕掩码和光标掩码的方法, 我不大明白, 只是照他的源代码抄了下来, 可是屏

幕上却仍不能显示出鼠标, 难道书的作者骗我? 我想不大可能, 但我却找不到其他原因了.

___________________________________________________

用画图方法显示鼠标的源代码:

文件1: NewMouse.h  
------------------
        一些基本的鼠标驱动以及画鼠标的函数。

//****************************************************
//*    Copyright (c)      Hidden Dragon       2005 - 8 - 28 *
//*                                                         *
//* File: NewMouse.h                                        *
//* ----------------                                        *
//*        Some operation function for mouse controling        *
//*                                                         *
//****************************************************

# include <dos.h>;
# include <conio.h>;
# include <stdlib.h>;
# include <graphics.h>;

enum   Bool          {False,True};

int mouseX, mouseY, button;                      // Mouse status arguments
int oldx, oldy;                                  // old position of mouse
int outarg_ax,outarg_bx,outarg_cx,outarg_dx,     // Out arguments
        outarg_al,outarg_bl,outarg_cl,outarg_dl;
int CurPxlClr,Cur_bk_Clr,CurDrawClr;             // Current Pixel Color
                                                 // Current Background Color
                                                 // Current Draw Color
// initialize mouse:
# define Success         1
# define Failure        -1

int initmouse()
{
        _AX = 0;
        geninterrupt(0x33);

        outarg_ax = _AX;        // outarg_ax = -1   | Mouse install success
                                // outarg_ax = 0    | Mouse install failure
        outarg_bx = _BX;         // the number of buttons in mouse

        if(outarg_ax == -1)     return(Success);
        else if(outarg_ax == 0) return(Failure);
        else                    return 0;        // Unknown Error
}

//get mouse status and its location:
void getmouse()
{
        _AX = 3;
        geninterrupt(0x33);
        button = (_BL);
        mouseX = (_CX);
        mouseY = (_DX);
}


/*                                                                    */
/*        DrawMouse Function: Draw a mouse with shape pointer     */
/*                 这个函数将画出一个指针形的鼠标图形。            */
/*                                                                 */
#define RATE        6

void DrawMouse(int X,int Y,int rate)         // rate 是你准备将鼠标显示多大, 1 最小,
                                             // 2 号要大一点, 如此类推  
{
        int poly[10];
        int BorderClr,FillClr;               // Border color of mouse, and
                                             // Fill color of mouse.

        poly[0] = X;                         // point A
        poly[1] = Y;

        poly[2] = poly[0]+rate*RATE;         // point B
        poly[3] = poly[1]+rate*(2*RATE);

        poly[4] = poly[0]+rate*RATE;         // point C
        poly[5] = poly[1]+rate*RATE;

        poly[6] = poly[0]+rate*(2*RATE);     // point D
        poly[7] = poly[1]+rate*RATE;

        poly[8] = poly[0];                   // point E ( A )
        poly[9] = poly[1];

        Cur_bk_Clr = getbkcolor();
        if(Cur_bk_Clr == WHITE)
        {
                setbkcolor( LIGHTGRAY );
                Cur_bk_Clr = getbkcolor();
        }
        CurDrawClr = getcolor();
        if(Cur_bk_Clr == CurDrawClr)setcolor(CurDrawClr^15);

        setwritemode(XOR_PUT);
        line(poly[0],poly[1],poly[2]-1,poly[3]-1); // line AB
        line(poly[2],poly[3],poly[4]  ,poly[5]+1); // line BC
        line(poly[4],poly[5],poly[6]-1,poly[7]  ); // line CD
        line(poly[6],poly[7],poly[8]+1,poly[9]  ); // line DA
        setwritemode(COPY_PUT);

        setcolor(CurDrawClr);
}

//*
//* Function: gmouse(oldx,oldy,rate)
//* --------------------------------
//*         run in graphics mode
//*
void gmouse(int oldx,int oldy,int rate)
{
        static int mouseflag = 0;         // mouse has never been drawed

        if(mouseflag == 1)                // once mouse be drawed, mouseflag
                                          // will == 1
                DrawMouse(oldx,oldy,rate); // erase old mouse

        getmouse();                       // get new status of mouse
        DrawMouse(mouseX,mouseY,rate);
        mouseflag = 1;                    // mouse has been drawed
}

//*
//* Function: ShowMouse()
//* ---------------------
//*         Can only run in graphics mode, and it must be used in for-//* loop
//*        statement. Like this:
//*                for(..;..;..)
//*                {
//*                        ShowMouse();
//*                        ...
//*                }
//*
void ShowMouse( int rate )
{
        gmouse( oldx, oldy, rate );
        oldx = mouseX;
        oldy = mouseY;
        getmouse();
        for(;oldx==mouseX&&oldy==mouseY&&kbhit()==0;)
                getmouse();
}

//*
//* Function: showmouse()
//* ---------------------
//*         Can only run in text mode
//*
void showmouse()
{
        _AX=1;
        geninterrupt(0x33);
}

//*
//* Function: hide mouse()
//* ----------------------
//*         Can only run in text mode
//*
void hidemouse()
{
        _AX=2;
        geninterrupt(0x33);
}


/*                                                                */
/*        Button Function: to test which button is pressed        */
/*                                                                  */
int Button(int button_code)
{
        _AX=5;
        _BX=button_code;
        geninterrupt(0x33);

        outarg_ax=_AX;
        outarg_bx=_BX;
        outarg_cx=_CX;
        outarg_dx=_DX;

        return(outarg_bx);
}

/*                                                                */
/*        ButtonUp Function: to test the status of button up      */
/*                                                                */
int ButtonUp(int button_code)
{
        _AX = 6;
        _BX = button_code;
        geninterrupt(0x33);

        outarg_ax=_AX;
        outarg_bx=_BX;
        outarg_cx=_CX;
        outarg_dx=_DX;

        return(outarg_bx);
}

/*                                                                */
/*        SetMouseLoc Function: to set the location of mouse      */
/*                                                                */
void SetMouseLoc(int x,int y)
{
        _AX = 4;
        _CX = x;
        _DX = y;
        geninterrupt(0x33);
}


文件2:NewDraw.c
-------------------
        这是一个我未编完的程序, 不过也可运行, 只是什么也不能干, 但可以显示鼠标。 进入后会

有三个按钮。按'F' 键, 按钮“File”便会被按下。  鼠标经过按钮时, 按钮会加亮。 要退出,请按

“ESC”。



//************************************************************
//*  Copyright(c)    Hidden Dragon          2005 - 8 - 11    *
//*                                                          *
//* File : NEWDRAW.C                                         *
//* ----------------                                         *
//*          A little program for drawing                         *
//************************************************************

# include "newmouse.h"
# include <graphics.h>;
# include <conio.h>;


#define ESC        27                        // ASCII code of ESC key
#define EXIT        0
#define DRAW         1
#define EDIT        2
#define FILE        4
#define NONE         5

int  GraphDriver;                         // graphics device driver
int  GraphMode;                           // the Graph mode value
int  ErrorCode;                           // graph error code
int  choice;                              // choice made by user

enum Status { Unavailable, Unactive, Active, Highlight };

// Functions' Prototypes:
void WelcomeFace();           // Show Welcome face
void WorkFace();              // Draw a face for work
void Initialize();            // Initializes the graphics mode
void DrawMenu(int,int,int,int,char * ,int);
int  Choice();                // return the user's choice
int  MouseOn(int);            // judge if mouse is on a menu

//____________________  Main Function:  _______________________
void main()
{
        int  quit = False;
//        char buffer[80];

        Initialize();
        WelcomeFace();
        WorkFace();

        initmouse();
        getmouse();
        oldx = mouseX;
        oldy = mouseY;
//        vsprintf( buffer, "MouseX: %d;  MouseY: %d", mouseX, mouseY );

        // Work:
        for(; quit == False ;)
        {
                gotoxy( 55, 1 );
                printf( " X: %4d;  Y: %4d", mouseX, mouseY );
                ShowMouse( 2 );

                switch( Choice() )
                {
                case EXIT :
                        quit = True;          // normal exit
                        DrawMenu( 230, 4, 280, 18, "Exit", Active );
                        break;

           //        case DRAW : Draw(); break;

          //        case EDIT : Edit(); break;

                case FILE :
                        DrawMenu( 20, 4, 70, 18, "File", Active );
                        getch();
                        //File();
                        break;

                case NONE : break;

                default: break;
                }
                gotoxy( 55, 1 );
                printf( "                    " );
        }

    //        ExitFace();
}
//---------------------- Main Function Over  -----------------------

//*
//* Function: WelcomeFace()
//* -----------------------
//*         to draw a welcome face for ready to run main program.
//*
void WelcomeFace()
{
        outtext("Welcome");
        getch();
        cleardevice();
}

//*
//* Function: DrawMenu()
//* --------------------
//*         to draw the the menu button
//*
void DrawMenu(int left, int top, int right, int bottom, char * text,
                int status )
{
        setcolor( LIGHTGRAY );
        setfillstyle(SOLID_FILL, CYAN);
        bar3d( left, top, right, bottom, 0, 0 );
        switch( status )
        {
        case Unavailable:break;
        case Unactive:
                setcolor( LIGHTGRAY );
                line( left, top, right, top );
                line( left, top, left, bottom);
                setcolor( DARKGRAY );
                line( left, bottom, right, bottom );
                line( right, bottom, right, top );

                setcolor( RED );
                outtextxy( left + 10, top + (bottom-top)/4, text );
                setcolor( LIGHTGRAY );

                break;
        case Active:
                setcolor( DARKGRAY );
                line( left, top, right, top );
                line( left, top, left, bottom );
                setcolor( LIGHTGRAY );
                line( left, bottom, right, bottom );
                line( right, bottom, right, top );

                setcolor( YELLOW );
                outtextxy( left + 10, top + (bottom-top)/4, text );
                setcolor( LIGHTGRAY );
                break;
        case Highlight:
                setcolor( LIGHTGRAY );
                line( left, top, right, top );
                line( left, top, left, bottom );
                setcolor( DARKGRAY );
                line( left, bottom, right, bottom );
                line( right, bottom, right, top );

                setcolor( LIGHTRED );
                outtextxy( left + 10, top + (bottom-top)/4, text );
                setcolor( LIGHTGRAY );
                break;
        default: break;
        }
}

//*
//* Function: WorkFace()
//* --------------------
//*         to creat a work face.
//*
void WorkFace()
{
        setcolor( BLUE );
        setfillstyle(SOLID_FILL,BLUE );
        bar3d( 1, 1, getmaxx(), 20, 0, 0 );
        setcolor( LIGHTGRAY );
        setfillstyle( SOLID_FILL, LIGHTGRAY );
        bar3d( 1, 21, getmaxx(), getmaxy(), 0, 0 );

        DrawMenu( 20, 4, 20+50, 18, "File", Unactive );
        DrawMenu( 70+20, 4, 70+20+50, 18, "Edit",Unactive );
        DrawMenu( 160, 4, 160+50, 18, "Draw", Unactive );
        DrawMenu( 210+20, 4, 230+50, 18, "Exit", Unactive );
}

//*
//* Function: MouseOn()
//* -------------------
//*         Judge if mouse is on a menu. If true, return True, else return False.
//*
int MouseOn( int Menu )
{
        getmouse();
        switch( Menu )
        {
        case FILE:
                if( mouseX>;=20&&mouseX<=70&&mouseY>;=4&&mouseY<=18 )
                        return True;
                else return False;
        case EDIT:
                if( mouseX>;=90&&mouseX<=140&&mouseY>;=4&&mouseY<=18 )
                        return True;
                else return False;
        case DRAW:
                if( mouseX>;=160&&mouseX<=210&&mouseY>;=4&&mouseY<=18 )
                        return True;
                else return False;
        case EXIT:
                if( mouseX>;=230&&mouseX<=280&&mouseY>;=4&&mouseY<=18 )
                        return True;
                else return False;
        default: return False;
        }
}
//*
//* Function: Choice()
//* ------------------
//*         to return the choice user has made.
//*
int Choice()
{
        int choice;

        if( kbhit()!=0 )
                choice = getch();
        else if(MouseOn(FILE))
        {
                DrawMenu( 20, 4, 70, 18, "File", Highlight );
        }
        else if(MouseOn(EDIT))
        {
                DrawMenu( 90, 4, 140, 18, "Edit", Highlight );
        }
        else if(MouseOn(DRAW))
        {
                DrawMenu( 160, 4, 210, 18, "Draw", Highlight );
        }
        else if(MouseOn(EXIT))
        {
                DrawMenu( 230, 4, 280, 18, "Exit", Highlight );
        }
        else
        {
                DrawMenu( 20, 4, 70, 18, "File", Unactive );
                DrawMenu( 90, 4, 140,18, "Edit", Unactive );
                DrawMenu( 160,4, 210,18, "Draw", Unactive );
                DrawMenu( 230,4, 280,18, "Exit", Unactive );
        }
        if( MouseOn(FILE) && button == 1 ) choice = FILE;
        if( MouseOn(EDIT) && button == 1 ) choice = EDIT;
        if( MouseOn(DRAW) && button == 1 ) choice = DRAW;
        if( MouseOn(EXIT) && button == 1 ) choice = EXIT;

        switch(choice)
        {
        case 27: return ( EXIT );

        case FILE:
        case 'F':
        case 'f': return ( FILE );

        case EDIT: return ( EDIT );

        case DRAW: return ( DRAW );

//        case EXIT: return ( EXIT );

        default: return ( NONE );
        }
}

//*
//* Function: Initialize()
//* ----------------------
//*        Initializes the graphics mode.
//*
void Initialize(void)
{
  GraphDriver = DETECT;                 /* Request auto-detection        */
  registerbgidriver(EGAVGA_driver);     /* Appendixed by Hidden Dragon
                                        /* for independent run          */
  initgraph( &GraphDriver, &GraphMode, "..\\bgi" );
  ErrorCode = graphresult();                /* Read result of initialization*/
  if( ErrorCode != grOk ){                /* Error occured during init        */
    printf(" Graphics System Error: %s\n", grapherrormsg( ErrorCode ) );
    printf("\n Press any key to halt:");
    _setcursortype(_NOCURSOR);
    getch();
    exit( 1 );
  }
}


--------------------------------------------------------------------------------------

      打开程序看到Welcome 后按任意键即可进入.

--------------------------------------------------------------------------------------
        不知有哪位高手会用高级一点的方法(而不是用上面的画线方法)来显示鼠标的, 望不吝赐教



        [b]也希望交点 C 语言爱好者朋友!
       
        MY QQ:                37179130
        My E-mail:        [u]jacktinpig@sina.com[/u][/b][/b]

>>>> 鼠标编程的尝试和疑问

在DOS上玩这个还有意义么?
看看INT 33H的接口,我记得是用两个位图叠加的。

>>>> 鼠标编程的尝试和疑问

一般是用数组来表示光标的形状极其掩码的
比如
static int maskshand
{
           //screen mask
           0xE1FF,//111000011111111
           0xE1FF,//111000011111111
           0xE1FF,//111000011111111
           0xE1FF,//111000011111111
           0xE000,//111000000000000
           0xE000,//111000000000000
           0xE000,//111000000000000
           0xE000,//111000000000000
           0xE000,//111000000000000
           ......................
           //cursor mask
           0x1E00,//000111100000000
           0x1E00,//000111100000000
           0x1E00,//000111100000000
           0x1E00,//000111100000000
           ......................
}
然后调用INT 33H中断

楼主可以找本手册来看, 我有本94年的微软的鼠标器程序员手册(中文),你要喜欢可以送给你,里面什么都有,不过都是DOS底下的:)

>>>> 鼠标编程的尝试和疑问

谢谢你!
   你说的方法我也看过书,并尝试过,但是却不能显示鼠标, 书上说得并不详细, 我也不知道错在哪里.
    你的书我真的有兴趣, 如果可以送给我的话, 请寄:
         [u][b] 苏州大学校本部
          前化 4 号楼 414[/b][/u]                     
这里先谢过了!

>>>> 鼠标编程的尝试和疑问

看看鼠标指针是不是被关闭了。只有关闭了鼠标指针,你才能画一个来替代它。
因此,我觉得之所以你调用33H接口不起作用,原因大概在这里吧?

>>>> 鼠标编程的尝试和疑问

-->

邮编呢?
你的名字叫前化 :em14: 好奇怪的 :m01:

>>>> 鼠标编程的尝试和疑问

_________________
邮编是 [b]215006[/b]
---------------------------

之所以叫前化, 是因为我们宿舍在学校的前进化工厂旁边, 呵呵...

再一次向你致谢!!!

>>>> 鼠标编程的尝试和疑问

l兄够慷慨。还得自贴邮费。
不知道L兄还有没有其它书可送?呵呵。

>>>> 鼠标编程的尝试和疑问

-->
接触电脑比较早,所以过时的东西比较多 :oops:
很多都送人了,还有qbasic入门,怎样学用Turbo C之类的,不知道你要不要
:mrgreen:  :mrgreen:  :mrgreen:
刚才是看楼主还在仔细研究DOS,被感动了 :em06: 所以免费送

不过还是得提醒楼主一句
不要太沉迷于过时的东西了 :P


assiss兄你是主动要的,那你的就先发个信给我,不过里面得附足邮票或者邮资 :mrgreen:

>>>> 鼠标编程的尝试和疑问

多谢luojannx兄的提醒, 不知兄台正在研究当前的哪些前沿啊, 可否告知一二.
我并非只对过时的东西感兴趣的. :D

>>>> 鼠标编程的尝试和疑问

好长的代码:(

>>>> 鼠标编程的尝试和疑问

-->

以前也跟你一样 :P
喜欢调用中断, 以及凡是那些涉及到底层的东西,比如硬件直接写屏什么的
另外喜欢图形方面的东东

大学以后开始玩linux,并开始玩单片机什么的,什么都玩,不过偏爱单片机一点,另外svgalib,libsdl,gtk,工控PLC,串口通讯也挺爱玩的,后来大三开始玩游戏,结果什么都偏废了

现在么,跟前沿沾不上边,C语言也才刚拣起来呢,正准备全面的学习一下unix及C++还有数据结构算法之类的东东, 以后还是搞点嵌入式之类的好了,来钱快 :mrgreen:

另外,我明天出去旅游,要8天后才能回来,到时再给你寄书(这几天准备旅游的事情去了,没空 :oops: )

>>>> 鼠标编程的尝试和疑问

luojiannx      真潇洒.

>>>> 鼠标编程的尝试和疑问

>>>> 鼠标编程的尝试和疑问

回来以后先来CU啊.呵呵.这里不能少了你.

>>>> 鼠标编程的尝试和疑问

>>>> 鼠标编程的尝试和疑问

说起图形有个问题不解...

记得dos下有图形模式的...可以做小游戏.
为什么没看到linux console下的图形模式的呢????
难道非得在X下实现???

>>>> 鼠标编程的尝试和疑问

经常听到单片机, 单片机是什么东东?



Copyright © 1999-2000 LSLNET.COM. All rights reserved. 蓝森林网站 版权所有。 E-mail : webmaster@lslnet.com