搜索
bottom↓
回复: 31

我的串口屏如何响应UI中的按钮,求个思路?

  [复制链接]

出0入0汤圆

发表于 2013-12-5 16:04:43 | 显示全部楼层 |阅读模式
如图,做的串口屏,做了UI按钮,却一直没有想到好的响应方式,代码很傻瓜的去读坐标,比坐标,再判断按键,再更新显示框,不知道有没有好的按钮响应处理思想,没太接触过操作系统,看了看WINDOWS 的消息机制,但好像套用起来一是思维还不太习惯,二是代码量好像很大,还要很好的结构体封装,好的架构才能实现。   
-------------------------分割线-------------------------------
图片手机拍的,不太好看。
有好的思想的,交流下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-12-5 16:11:10 | 显示全部楼层
沉得好快。呵呵,一看大部分资讯信息啊。自己再顶一下吧。

出0入296汤圆

发表于 2013-12-5 17:52:04 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-12-5 18:20 编辑

简单来说这么处理的

屏幕上的按钮和文本框都是一个矩形区域,你可以定义一个数据结构

  1. typedef struct {
  2.     int nTop;
  3.     int nLeft;
  4.     int nWidth;
  5.     int nHeigh;
  6. }rect_t;
复制代码

然后为屏幕上所有的对象串起来:

  1. typedef struct control_t control_t

  2. struct control_t {
  3.     rect_t tWindow;
  4.     control_t *ptNext;
  5. };

  6. static control_t *s_ptControls = NULL;

  7. control_t *get_controls(void)
  8. {
  9.     return s_ptControls;
  10. }
复制代码


每次获得触摸信息以后,通过这个链表来依次扫描看看落在哪个区域里面了,如果落入了,你懂得。
另外,实际上这个链表还可以作为刷新的顺序,GUI术语上叫做Z-Order。你可以把它做成双链表,
这样还可以实现windows上窗体覆盖,激活的效果。

希望对你有所帮助。这里提到的只是最小实现,复杂一点的窗体结构还可以在control_t里面加入
更多的元素,比如如何绘制这个窗体啊之类的信息,窗体是否被按下了啊,是否处于激活状态啊,
文本信息是什么啊……,另外如果把窗体做成一个容器……你懂的。

事件处理其实并不复杂,下面以简单的Click事件为例子:
首先,你要定义一个事件处理程序的函数原型

  1. typedef struct {
  2.     int x,
  3.     int y
  4.     //其它你想附加的信息
  5. }key_event_t;

  6. typedef bool click_event_t(key_event_t *ptEvent);
复制代码


然后更新control_t类:

  1. struct control_t {
  2.     rect_t tWindow;
  3.     control_t *ptNext;

  4.     click_event_t *fnClickEvent;
  5. };
复制代码


增加一个事件处理程序的注册函数


  1. //! 小把戏,你懂的
  2. #define this    (*ptThis)

  3. bool control_register_click_event_handler(control_t *ptThis, click_event_t *fnHandler)
  4. {
  5.     if (NULL == ptThis || NULL == fnHandler) {
  6.         return false;
  7.     }
  8.    
  9.     this.fnClickEvent = fnHandler;

  10.     return true;
  11. }
复制代码


最后我们就可以编写一个程序,根据输入的x,y来触发对应的按键的程序了:

  1. bool controls_check_click_event(control_t *ptThis, int x, int y)
  2. {
  3.     if (NULL == ptThis) {
  4.         return false;
  5.     }

  6.     //! 搜索链表
  7.     do {
  8.         if (check_is_point_in_rect(&this.tWindow, x, y)) {
  9.              //! 点落在矩形里面了
  10.              if (NULL != this.fnClickEvent) {
  11.                   //! 调用相应的消息处理程序
  12.                   key_event_t tEvent = {x, y};
  13.                   this.fnClickEvent(&tEvent);
  14.                   return true;
  15.              }
  16.         }
  17.         
  18.         //! 继续搜索
  19.         ptThis = this.ptNext;
  20.     } while(NULL != ptChain);

  21.     //! 如果运行到这里,说明什么都没有搜索到
  22.     return false;
  23. }
复制代码



出0入0汤圆

发表于 2013-12-5 18:21:17 | 显示全部楼层
楼上高端大气上档次啊

出0入0汤圆

发表于 2013-12-5 18:36:25 来自手机 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-5 17:52
简单来说这么处理的

屏幕上的按钮和文本框都是一个矩形区域,你可以定义一个数据结构

够详细。。新书出了没

出0入8汤圆

发表于 2013-12-5 19:28:00 | 显示全部楼层
霸气,好好看看,

出0入8汤圆

发表于 2013-12-5 19:37:18 | 显示全部楼层
霸气~~~~~~~~~~~~~~

出0入0汤圆

发表于 2013-12-5 19:38:42 | 显示全部楼层
学习大神的方法!!!

出0入296汤圆

发表于 2013-12-5 23:14:10 | 显示全部楼层
MINI2440 发表于 2013-12-5 18:36
够详细。。新书出了没

还没…以我这种王婆卖瓜的个性,出了还不满世界的吹~

出0入0汤圆

发表于 2013-12-6 08:22:21 来自手机 | 显示全部楼层
我是来听课的。

出0入0汤圆

发表于 2013-12-6 09:05:22 | 显示全部楼层

出0入0汤圆

发表于 2014-1-1 00:47:02 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-5 17:52
简单来说这么处理的

屏幕上的按钮和文本框都是一个矩形区域,你可以定义一个数据结构

出0入0汤圆

发表于 2014-1-6 00:34:00 | 显示全部楼层
看一下            

出0入0汤圆

发表于 2014-5-24 09:06:11 来自手机 | 显示全部楼层
默默收藏

出0入0汤圆

发表于 2014-8-7 02:44:06 来自手机 | 显示全部楼层
强悍,收藏一下。

出0入0汤圆

 楼主| 发表于 2016-6-7 16:50:58 | 显示全部楼层
本帖最后由 xf331785508 于 2016-6-7 17:04 编辑

根据傻孩子的砖,我斗胆晒一下我的糟玉。以飨坛友。


  1. #include <string.h>
  2. #include "TSP.h"
  3. #ifndef     COUNTOF
  4. #define     COUNTOF(__a)  ((sizeof((__a)))/(sizeof(*(__a))))
  5. #endif

  6. /*
  7. gTouchXYUpdateFlag was changed in interrupt function
  8. */
  9. volatile bool gTouchXYUpdateFlag = FALSE;
  10. // Temporary save datas from touch screen to buffer
  11. u8   gReceiveBuffer[MAX_RECEIVE_BUFFER] = {0};
  12. u32  gRxCounter = 0;


  13. /* Retangle assign */
  14. static Rectangle_Typedef  *Rectangle_TypedefAssign(Rectangle_Typedef *pRect, u16 left, u16 top, u16 width, u16 height)
  15. {
  16.         if( NULL == pRect )
  17.         {
  18.                 return NULL;
  19.         }
  20.         pRect->nLeft   = left;
  21.         pRect->nTop    = top;
  22.         pRect->nWidth  = width;
  23.         pRect->nHeight = height;
  24.         return pRect;
  25. }

  26. /* Control block assign for each element */
  27. static Control_Typedef *Control_TypedefAssign
  28. (Control_Typedef     *pCtrl,
  29. Rectangle_Typedef   *pWindow,
  30. Control_Typedef     *pNext,
  31. ClickEvent          *pfn,
  32. u32                 indexOf,
  33. u8                  captionNums,
  34. char                *str,
  35. u32                 reserve)
  36. {
  37.         if( NULL == pCtrl )
  38.         {
  39.                 return NULL;
  40.         }
  41.         pCtrl->tWindow      = pWindow;
  42.         pCtrl->ptNext       = pNext;
  43.         pCtrl->fnClickEvent = pfn;
  44.         pCtrl->index        = indexOf;
  45.         pCtrl->charNums     = captionNums;
  46.         pCtrl->btnCaption   = str;
  47.         pCtrl->timeOfCycle  = reserve;
  48.         return pCtrl;
  49. }

  50. /* Translate the location of the button which was pressed
  51. * from USART interface buffer. */
  52. TOUCH_XY AnalysisTouchXY(void)
  53. {
  54.         u8 i = 0;
  55.         TOUCH_XY touchXY = {0, 0};
  56.         if( gTouchXYUpdateFlag )
  57.         {
  58.                 for(i = 0; i < COUNTOF(gReceiveBuffer); i++)
  59.                 {
  60.                         if((gReceiveBuffer[i] == CMD_HEAD) && (gReceiveBuffer[i + 1] == RETURN_TOUCHSCREEN_XY))
  61.                         {
  62.                                 touchXY.x = (u16)((gReceiveBuffer[i + 2] << 8) | gReceiveBuffer[i + 3]);
  63.                                 touchXY.y = (u16)((gReceiveBuffer[i + 4] << 8) | gReceiveBuffer[i + 5]);
  64.                                 gTouchXYUpdateFlag = FALSE;
  65.                                 memset(gReceiveBuffer, 0, sizeof(gReceiveBuffer));
  66.                                 gRxCounter = 0;
  67.                                 break;
  68.                         }
  69.                 }
  70.         }
  71.         return touchXY;
  72. }

  73. /* According the location to return the index of button retangle which was pressed. */
  74. u8 RtnTouchScreenRst(TOUCH_XY tp, const RETANGLE_AREA *pArea)
  75. {
  76.         u8 equivalentKey = KEY_NONE;
  77.        
  78.         if( NULL == pArea )
  79.         {
  80.                 return equivalentKey;
  81.         }
  82.         if((tp.x >= (pArea->sx)) && (tp.x <= (pArea->ex)) &&
  83.            (tp.y >= (pArea->sy)) && (tp.y <= (pArea->ey)))
  84.         {
  85.                 equivalentKey = pArea->areaNo;
  86.         }
  87.         return equivalentKey;
  88. }

  89. /* To check the range of location */
  90. bool CheckPointinRectangle(Rectangle_Typedef *ptRect, u16 x, u16 y)
  91. {
  92.         if( NULL == ptRect )
  93.         {
  94.                 return FALSE;
  95.         }
  96.         if((x >= ptRect->nLeft) && (x <= (ptRect->nLeft + ptRect->nWidth)))
  97.         {// x is in the range
  98.                 if((y >= ptRect->nTop) && (y <= (ptRect->nTop + ptRect->nHeight)))
  99.                 {// y is in the range
  100.                         return TRUE;
  101.                 }
  102.                 else{
  103.                         return FALSE;
  104.                 }
  105.         }
  106.         else{
  107.                 return FALSE;
  108.         }
  109. }

  110. /* To find the correct button and call back the right handler which was defined. */
  111. s32 ControlsCheckClickEvent(Control_Typedef *ptThis, KEY_EVENT_Typedef *ptKeyValue)
  112. {
  113.     if ((NULL == ptThis) || (NULL == ptKeyValue))
  114.         {
  115.         return FAULT;
  116.     }
  117.     do {
  118.                 if (CheckPointinRectangle((ptThis->tWindow), ptKeyValue->x, ptKeyValue->y))
  119.                 {
  120.                         if ( NULL != ptThis->fnClickEvent )
  121.                         {
  122.                                 return (ptThis->fnClickEvent(ptKeyValue, &(ptThis->index)));
  123.                         }
  124.                         else{
  125.                                 return FAULT;
  126.                         }
  127.                 }
  128.         ptThis = ptThis->ptNext;
  129.     } while(NULL != ptThis);
  130.     return FAULT;
  131. }


  132. /* Button's retangle drawing */
  133. static void  AppLCM_Buttons(u8 btnNums, bool isBtnDraw, Rectangle_Typedef *ptRect, Control_Typedef *ptCtrl)
  134. {
  135.         register u8 i = 0;
  136.        
  137.         if( NULL == ptRect  ||  NULL == ptCtrl )
  138.         {
  139.                 return NULL;
  140.         }
  141.         if( isBtnDraw )
  142.         {
  143.                 for(i = 0; i < btnNums; i++)
  144.                 {
  145.                         LCM_ButtonDraw((ptRect + i)->nLeft,  (ptRect + i)->nTop,
  146.                                        (ptRect + i)->nWidth, (ptRect + i)->nHeight,
  147.                                                    BUTTON_COLOR,
  148.                                                    (ReturnCharacterNumber((ptCtrl + i)->btnCaption) >> 1),
  149.                                                    (ptCtrl + i)->btnCaption);
  150.                 }
  151.         }
  152. }

  153. /* According the index of key in keyboard to return the correct retangle's location. */
  154. static TOUCH_XY Convert2XY(u16 keyValue, Control_Typedef  *ptThis)
  155. {
  156.         TOUCH_XY  rtnXY = {0, 0};
  157.        
  158.         if( NULL == ptThis )
  159.         {
  160.                 return rtnXY;
  161.         }
  162.     do {   
  163.         if ( KEY == ptThis->index )
  164.                 {
  165.                         rtnXY.x = ptThis->tWindow->nLeft + 1;
  166.                         rtnXY.y = ptThis->tWindow->nTop  + 1;
  167.                         KEY = KEY_NONE;
  168.                         return rtnXY;               
  169.         }
  170.             ptThis = ptThis->ptNext;
  171.     } while(NULL != ptThis);
  172.     return rtnXY;
  173. }




  174. void AppLCM_UserInterfaceProcess(u8 btnNums, bool isBtnDraw, Rectangle_Typedef *ptRect, Control_Typedef *ptCtrl)
  175. {

  176.         bool  isReturn = TRUE;
  177.         u32   counter = 0;
  178.         KEY_EVENT_Typedef keyEvent = {0,0};
  179.        
  180.         if( NULL == ptCtrl  ||  NULL == ptRect )
  181.         {
  182.                 return;
  183.         }
  184.         KEY = KEY_NONE;
  185.         AppLCM_Buttons(btnNums, isBtnDraw, ptRect, ptCtrl);       
  186.         if( ((ptCtrl->timeOfCycle) == 0) || ((ptCtrl->timeOfCycle & 0xFFFF0000) != 0) ){
  187.                 ptCtrl->timeOfCycle = 0xFFFF;
  188.         }
  189.         do
  190.         {
  191.                 if(KEY != KEY_NONE){
  192.                         gTchLoc = Convert2XY(KEY, ptCtrl);
  193.                         KEY = KEY_NONE;          
  194.                 }
  195.                 else{
  196.                         gTchLoc = AnalysisTouchXY();
  197.                 }
  198.                 keyEvent.x = gTchLoc.x;
  199.                 keyEvent.y = gTchLoc.y;
  200.                 delay_ms(50);
  201.                 switch(ControlsCheckClickEvent(ptCtrl, &keyEvent))
  202.                 {
  203.                         case QUIT:       
  204.                                         isReturn = FALSE;
  205.                                         ptCtrl->timeOfCycle &= 0x0000FFFF;             
  206.                                         ptCtrl->timeOfCycle |= (keyEvent.x << 16);
  207.                         break;
  208.                         case CYCLE:       
  209.                         break;
  210.                         case REDRAW:
  211.                                         counter = 0;
  212.                                         AppLCM_Buttons(btnNums, isBtnDraw, ptRect, ptCtrl);
  213.                         break;
  214.                         case FAULT:       
  215.                         break;
  216.                         default:
  217.                         break;
  218.                 }
  219.                 counter++;
  220.         }while( (isReturn) && (counter < (ptCtrl->timeOfCycle))  );
  221. }



  222. static s32 AppLCM_ComSetHandler(KEY_EVENT_Typedef *ptEvent, u32 *btnNo)
  223. {
  224.         ptEvent = ptEvent;
  225.         switch(*btnNo)
  226.         {
  227.                 case NO:
  228.                         return QUIT;
  229.                 case 1:
  230.                         Process1();
  231.                         return CYCLE;
  232.                 case 2:
  233.                         Process2();
  234.                         return REDRAW;
  235.                 case 3:
  236.                         Process3();
  237.                         return CYCLE;
  238.                 default:
  239.                 return CYCLE;
  240.         }
  241. }


  242. void  AppLCM_ComSetSubMenu(void)
  243. {
  244.         Rectangle_Typedef rect[4] = {0};
  245.         Control_Typedef ctrl[COUNTOF(rect)] = {0};
  246.         Rectangle_TypedefAssign(&rect[0], SUBMENU_TITLE_X, SUBMENU_TITLE_Y, CHAR_WIDTH(FONT_WIDTH_32, 4), BUTTON_HEIGHT);
  247.         Rectangle_TypedefAssign(&rect[1], SM_COLUM2_BUTTON_X, SM_ROW1_BUTTON_Y, CHAR_WIDTH(FONT_WIDTH_32, 5), BUTTON_HEIGHT);
  248.         Rectangle_TypedefAssign(&rect[2], SM_COLUM2_BUTTON_X, SM_ROW2_BUTTON_Y, CHAR_WIDTH(FONT_WIDTH_32, 5), BUTTON_HEIGHT);
  249.         Rectangle_TypedefAssign(&rect[3], SM_COLUM2_BUTTON_X, SM_ROW3_BUTTON_Y, CHAR_WIDTH(FONT_WIDTH_32, 6), BUTTON_HEIGHT);
  250.         Control_TypedefAssign(&ctrl[0], &rect[0],  &ctrl[1],  AppLCM_ComSetHandler,  NO, 4, "Com Setting", 0);
  251.         Control_TypedefAssign(&ctrl[1], &rect[1],  &ctrl[2],  AppLCM_ComSetHandler,  1, 5, "1.Process1", 0);
  252.         Control_TypedefAssign(&ctrl[2], &rect[2],  &ctrl[3],  AppLCM_ComSetHandler,  2, 5, "2.Process2", 0);
  253.         Control_TypedefAssign(&ctrl[3], &rect[3],  NULL,      AppLCM_ComSetHandler,  3, 6, "3.Process3", 0);

  254.         AppLCM_UserInterfaceProcess(COUNTOF(rect), TRUE, rect, ctrl);
  255. }
复制代码


头文件如下:


  1. #ifndef  __TSP_H__
  2. #define  __TSP_H__

  3. #include "stm32f10x.h"
  4. /* MAX RECEIVE BUFFER */
  5. #define MAX_RECEIVE_BUFFER    50u

  6. typedef enum {Vertical = 0, Horizontal}DisplayDirection;

  7. /* Define some states of button pressed */
  8. typedef enum
  9. {
  10.         FAULT      = -1,
  11.         QUIT       = 0x0011,
  12.         FUNCTION   = 0X0022,
  13.         CYCLE      = 0X0033,
  14.         REDRAW     = 0X0044
  15. }ClickEventState_Typedef;
  16.                                                  
  17. typedef struct  tagTOUCHXY
  18. {
  19.         u16 x;
  20.         u16 y;
  21. }TOUCH_XY;

  22. typedef struct tagRETANGLE_AREA
  23. {
  24.         u8  areaNo;
  25.         u16 sx;
  26.         u16 sy;
  27.         u16 ex;
  28.         u16 ey;
  29. }RETANGLE_AREA;

  30. /* the button's retangle */
  31. typedef struct {
  32.     u16 nLeft;
  33.     u16 nTop;
  34.     u16 nWidth;
  35.     u16 nHeight;
  36. }Rectangle_Typedef;

  37. /* The location of button which happened event. */
  38. typedef struct {
  39.     u16  x;
  40.     u16  y;
  41. }KEY_EVENT_Typedef;       
  42. /* Function point of event */
  43. typedef s32  ClickEvent(KEY_EVENT_Typedef *ptEvent, u32 *btnNo);
  44. /* Control block */
  45. typedef struct tagControl Control_Typedef;
  46. struct tagControl
  47. {
  48.         Rectangle_Typedef    *tWindow;         //Button Retangle
  49.         Control_Typedef        *ptNext;            //point to next struct class
  50.         ClickEvent                 *fnClickEvent;     //process this button which was being pressed
  51.         u32                          index;                       //the only index for the button on a UI picture
  52.         u8                           charNums;          //numbers of characters of the button's caption
  53.         char                         *btnCaption;      //string of button caption
  54.         u32                          timeOfCycle;      //reserved datas
  55. };



  56. #endif        //end of __TSP_H__



复制代码

出0入0汤圆

 楼主| 发表于 2016-6-7 17:18:17 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-5 17:52
简单来说这么处理的

屏幕上的按钮和文本框都是一个矩形区域,你可以定义一个数据结构

才补上代码,傻孩子大师看看代码冗余度如何?

出0入296汤圆

发表于 2016-7-1 10:32:52 | 显示全部楼层
xf331785508 发表于 2016-6-7 17:18
才补上代码,傻孩子大师看看代码冗余度如何?

能实现功能就是第一步,自己用着用着就能感觉出哪里是多余的。
这个代码至少我看起来还是很不错的!

出0入0汤圆

发表于 2016-8-5 19:19:17 | 显示全部楼层
好好消化..

出0入0汤圆

发表于 2016-8-5 21:53:57 | 显示全部楼层
学习了。

出0入0汤圆

发表于 2017-2-9 09:08:40 | 显示全部楼层
我是来打酱油的吗?
路过。。


出0入0汤圆

发表于 2017-2-9 13:57:07 | 显示全部楼层
顶一下,研究研究。

出0入0汤圆

发表于 2017-2-9 22:06:25 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2017-3-28 11:46:03 | 显示全部楼层
好好消化..

出5入10汤圆

发表于 2017-3-31 11:11:51 | 显示全部楼层
xf331785508 发表于 2016-6-7 16:50
根据傻孩子的砖,我斗胆晒一下我的糟玉。以飨坛友。

楼主你换页后,如果还有按键,且位置也不一样,你是怎么处理的?

出5入10汤圆

发表于 2017-3-31 11:19:34 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-5 17:52
简单来说这么处理的

屏幕上的按钮和文本框都是一个矩形区域,你可以定义一个数据结构

老师换页了(按键区域不一样了),怎么处理,结构体里面还要加什么元素?

出0入0汤圆

 楼主| 发表于 2017-3-31 13:25:41 | 显示全部楼层
chen849928055 发表于 2017-3-31 11:19
老师换页了(按键区域不一样了),怎么处理,结构体里面还要加什么元素?

在这个函数 AppLCM_ComSetSubMenu里面进行按钮坐标初始化。

出5入10汤圆

发表于 2017-4-24 16:59:14 | 显示全部楼层
楼主的ASCII码的字符感觉挺圆滑的,你是怎么做到的,普通的字摸软件生成的ASCII码字符好多锯齿

出0入0汤圆

 楼主| 发表于 2017-4-25 09:05:17 | 显示全部楼层
chen849928055 发表于 2017-4-24 16:59
楼主的ASCII码的字符感觉挺圆滑的,你是怎么做到的,普通的字摸软件生成的ASCII码字符好多锯齿 ...


字符看起来圆滑不圆滑,根字模软件无关,是单个象素点的尺寸大小决定的。楼主位的图片中LCM自带字模,可有多种大小的字体提供。  单象素点越小,同样字号的字体圆滑度越好,但也不是绝对的,假如象素点的尺寸足够小,同样字号的字体,肉眼可能就看不清了。  现在大家对surface的显示效果的批判就是这个原因,虽然细腻,但字太小,看着也不舒服。
如下图,同样的字号,借助放大镜,就展示了不同尺寸象素大小的显示效果。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出5入10汤圆

发表于 2017-4-25 09:15:54 | 显示全部楼层
xf331785508 发表于 2017-4-25 09:05
字符看起来圆滑不圆滑,根字模软件无关,是单个象素点的尺寸大小决定的。楼主位的图片中LCM自带字模,可 ...

是的,看emwin里有程序对字符显示做了抗锯齿化的处理,你可知道哪有类似emwin源码供参考吗?

出5入10汤圆

发表于 2017-4-27 11:24:04 | 显示全部楼层
楼主的菜单结构是裸机的,还是上了系统

出0入0汤圆

 楼主| 发表于 2017-4-27 13:52:23 | 显示全部楼层
chen849928055 发表于 2017-4-27 11:24
楼主的菜单结构是裸机的,还是上了系统


裸机的,没上系统。响应要求不高,另外,那时候能力有限,对伪并行状态机或RTOS不是很在行,所以直接上裸机,队列化运行。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-27 10:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表