摘要:有很多朋友不太明白UCGUI中如何实现透明窗体,虽然有些朋友曾经讨论过UCGUI中透明窗体的实现,但涉及到对UCGUI核心结构的改动, 本文深入解析UCGUI的透明窗体的支持原理,从剪切处理以及重绘方面全面讲解透明窗体的支持要点,并着手修改UCGUI以达到半透明窗体的效果,并不改动UCGUI的上层源码,而仅仅将修改局限于底层的LCD图形驱动当中,无须更改UCGUI本身。
       
目录
一. 透明处理的本质.
二. UCGUI中透明窗体支持.
三. MemDev下实现透明窗体的问题.
四. 透明窗体是否仅绘图时进行透明处理即可?
五. 修改后的代码下载.
一. 透明处理的本质。
1.透明显示的原理.
假设一张图片A与B,如果B是透明的,其意即,透明B可以看到A,但并不是完全看到A,只是看到A的朦胧的影象。在图形处理上,其实就是在A上面再显示B的时候,对B上面的每个点的颜色做了处理,简单的说就是与A的颜色按比例进行了一个混合,混合的时候是按照R、G、G分别进行混合的.
2.透明显示的计算公式
alpha是透明度,亦即显示B时B的每个象素点与A的相同位置的象素点进行混合的比例系数,R(b)_new/G(b)_new/B(b)_new为计算所得的新的B要显示的象素点的R/G/B颜色分量,R(b)/G(b)/B(b)为B本来象素点要显示的象素点的R/G/B颜色分量,R(a)/G(a)/B(a)为A的点的R/G/B颜色分量.
R(b)_new = R(b)*(1-alpha) + R(a)*alpha;
G(b)_new = G(b)*(1-alpha) + G(a)*alpha;
B(b)_new = B(b)*(1-alpha) + B(a)*alpha;
3.实现窗体透明显示面临的问题
经过这样合成之后,就可以获得B透明显示于A,即可以看到A又可以看到B的效果。但是这里其实也暗示了一个问题:
透明的图片B是在A的基础上显示的,即是在A显示之后再处理B,所以考虑一下我们下面要讨论的透明窗体:
[1].窗体要透明,则必须总是在不透明的窗体之后绘制,不然就会被其它窗体挡住了,这是窗体Z序的问题。
[2].透明的窗体不会对一般窗体构成遮挡关系,这是窗体剪切计算时的问题.
下面我们就将讨论一下UCGUI中如何利透明显示的知道实现透明窗体.
二. UCGUI中透明窗体支持。
1.UCGUI中窗体的Z序.
为了帮助理解透明窗体在剪切时的处理,这里有必要介绍一下UCGUI中z序的知识.有的朋友以为UCGUI中没有Z序,其实在窗体的最基本的结构WM_Obj当中,就包含了Z序:
typedef struct {
 GUI_RECT Rect;        /* outer dimensions of window */
 GUI_RECT InvalidRect; /* invalid rectangle */
 WM_CALLBACK* cb;      /* ptr to notification callback */
 WM_HWIN hNextLin;     /* Next window in linear list */
 WM_HWIN hParent;
  WM_HWIN hFirstChild;
 WM_HWIN hNext;
 U16 Status;           /* Some status flags */
} WM_Obj;
hNextLin----------所有窗体的链表指针,将UCGUI中所有的窗体形成一个键表,便于查找窗体。
hNext-------------兄弟窗体的链表指针,这个成员其实就表示了兄弟窗体的Z序关系,hNext所指窗体Z序高.
hParent-----------父窗体指体指针,父窗体被子孙窗体剪切.
hFirstChild-------第一个子窗体指针,用于快速查找窗体的所有子窗体.
Status------------窗体属性,如透明窗体/窗体是否可称动等.
Z序-----按照通行的解释,就是除平面的X/Y轴,抽象出来表示窗体层次关系的Z轴,沿着Z轴Z序增高,Z序高的窗体挡住Z序低的窗体.
注:依我理解,表达更详细一点以及加深理解, 可以把Z序理解成多层概念:
[1].兄弟窗体之间,Z序高的窗体高于Z序低的窗体的所有子孙窗体.
[2].父子窗体之间,子孙窗体Z序高于父窗体,但子孙窗体的区域不能超过父窗体.
根据UCGUI中的这个Z序,在剪切计算时如下的剪切规则:
[1].窗体被hNext之下的兄弟窗体剪切,以及被其父窗体的hNext之下兄弟窗体剪切,递归处理.
[2].窗体被子窗体剪切,注意只被第一级子窗体剪切[没有必要处理孙辈窗体,他们的区域被父窗体包含].
[3].子窗体不能超出父窗体区域.
2.UCGUI中透明窗体的具体支持.
UCGUI中实现的透明,是完全的透明,意即透明窗体相对于其它一般窗体完全不可见,这种完全不可见的的就是在剪切处理当中实现的,UCGUI中处理剪切时,透明窗体不会对其它一般窗体构成遮挡关系,无论是比其Z序高还是序低的窗体。在UCGUI中实现透明窗体,必须指定如下两个属性:
WM_CF_HASTRANS-----透明属性
WM_CF_STAYONTOP----始终为UCGUI中同一级兄弟窗体中z序最高的窗体,以最后指定该属性的窗体Z序最高.
[1].WM_CF_HASTRANS属性是透明窗体的基本属性,相关窗体的剪切处理部分,凡是指定了这个属性的窗体,在UCGUI中的剪切计算时,不会对其它窗体形成剪切关系;
[2].透明窗体会在其它Z序低的窗体重绘后,重绘透明窗体,以保证透明窗体不会被挡住。
[3].指定透明窗体WM_CF_STAYONTOP属性, 是为了实现透明窗体居于一般窗体的前台,这样透明窗体才不会被一般窗体挡住, 保持透明的效果.
[4].因为WM_CF_STAYONTOP属性是相对于同一层级兄弟窗体的,因此透明窗体也是相对于同一层级的兄弟窗体。
3.UCGUI中透明窗体的实现原理.
[1].剪切处理时的支持.
关于剪切计算,是UCGUI中比较难理解的地方,我这里仅仅指出剪切处理时,透明窗体不会对一般窗体构成剪切的地方。
UCGUI390版的剪切计算有三个主要函数_Findy1()/_Findx0()/_Findx1(),这三个函数分别是找出一个剪切矩形的x0/x1/y1点,y0点是已知的.查看这几个函数可以知道,在处理剪切时,首先会判断窗体的透明属性,如果是透明窗体,就再查找透明窗体的所有子窗体。
[2].画窗体时的支持.
透明窗体是不会变成无效窗体的,它的重绘都是其它窗体的重绘引起的,这样处理对于效率是有帮助的.在画窗体时,主要查看void WM__PaintWinAndOverlays(WM_PAINTINFO* pInfo);这个函数是处理窗体得绘的,它在处理完每个窗体的重绘之后会调用两个函数,这两个函数作用如下:
if (WM__TransWindowCnt != 0) {
    _PaintTransChildren(pWin);       /* Draw all transparent children */
    _PaintTransTopSiblings(hWin, pWin);    /* Draw all transparent top level siblings */
}
_PaintTransChildren()-------重绘刚才绘制窗体的所有透明子窗体,保证透明窗体显示在其上层。
_PaintTransTopSiblings()----重绘刚才绘制窗体之上的所有透明窗体,保证位于其上的透明窗体显示在上层。
[注:位于一个窗体之上的窗体,包括其hNext之下的兄弟窗体,以及位于其父辈窗体的hNext之下的兄弟窗体]
[3].UCGUI为了支持透明窗体,已经将窗体绘制与剪切处理复杂处理了,而且还必须处理因为一般窗体重绘而引起透明窗体的重绘(当有相交区域时),因此透明窗体比起一般窗体在效率下是比较低下的.
4.如何增加UCGUI中透明窗体的透明度支持.
综上分析,UCGUI中已经实现了透明窗体所须的各种属性,如此我们所需要做的工作就非常的简单了,仅仅须要提供2D层次实际绘图的透明处理即可,UCGUI中2D图形库是所有绘图的基础,它自己的基础则是更下一层的驱动级的绘点函数,所以仅须实现绘点函数的透明处理,就实现了UCGUI中的透明窗体支持。
以下以模拟器中的处理透明,来说明透明窗体支持(如果是在真实硬件下,其改动也类似,仅须提供相应的Alpah画点函数),改动如下:
[1].增加一个全局变量g_AlphaValue,用于记录当前绘图透明度。
[2].增加设置/获取Alpha透明度的函数SetAlpha()/GetAlpha(),进行透明绘图时SetAlpha(60),完成透明绘图后恢复SetAlpha(0);
[3].增加一个带透明处理的绘点函数LCDSIM_SetPixelIndexAlpha().
透明效果图如下:
[示例是UCGUI390T版提供的示例XEye.c]
http://www.ucgui.com/ucgui/XEye.rar
http://www.ucgui.com/ucgui/image/UCGUI_Alpha.bmp
在透明窗体当中,处理绘图时要增加透明度的设置,如下:
 case WM_PAINT:
    State.x -= WM_GetWindowOrgX(hWin);
    State.y -= WM_GetWindowOrgY(hWin);
    SetAlpha(60); //设置要绘图的透明度60%.
    GUI_SetBkColor(GUI_BLUE);
    GUI_Clear();
    _DrawEye(EYE_X1, EYE_Y, EYE_RX, EYE_RY, State.x, State.y);
    _DrawEye(EYE_X2, EYE_Y, EYE_RX, EYE_RY, State.x, State.y);
    SetAlpha(0); //恢复透明度为0,即以下绘图不再进行透明处理.
   
[特别注意:透明窗体当中的绘制操作,会进行叠加透明处理,因此绘图时要注意相同区域的反复绘画]
   
5.具体的代码修改说明.
代码改动有三处地方,涉及两个文件LCDWin.c及LCDSim.c,主要是绘点宏定义的更改以及设置透明度的增加,具体的代码改动如下:
[1].在模拟器的LCDWin.c当中,增加如下代码:
//houhh 20061211...
unsigned g_AlphaValue = 0;
void SetAlpha(unsigned alpha);
void SetAlpha(unsigned alpha)
{
    g_AlphaValue = alpha*256/100;
}
[2].在LCDWin.c当中,修改SETPIXEL画点的宏定义成如下:
#ifdef _DEBUG
static int _CheckBound(unsigned int c) {
 unsigned int NumColors = LCD_BITSPERPIXEL > 8 ? 0xffff : (1 << LCD_BITSPERPIXEL) - 1;
 if (c > NumColors) {
    GUI_DEBUG_ERROROUT("LCDWin::SETPIXEL: parameters out of bounds");
    return 1;
 }
 return 0;
}
/* 2006-12-11 13:36:31
 #define SETPIXEL(x, y, c) \
    if (!_CheckBound(c)) { \
      LCDSIM_SetPixelIndex(x, y, c, LCD_DISPLAY_INDEX); \
    }*/
#define SETPIXEL(x, y, c) if (!_CheckBound(c)){\
    if(g_AlphaValue == 0){\
       LCDSIM_SetPixelIndex(x, y, c, LCD_DISPLAY_INDEX);}\
    else{\
       LCDSIM_SetPixelIndexAlpha(x, y, c, LCD_DISPLAY_INDEX, g_AlphaValue);\
    }\
}
#else
//houhh 20061211...
// #define SETPIXEL(x, y, c) LCDSIM_SetPixelIndex(x, y, c, LCD_DISPLAY_INDEX)
#define SETPIXEL(x, y, c) if(g_AlphaValue == 0){\
    LCDSIM_SetPixelIndex(x, y, c, LCD_DISPLAY_INDEX);}\
else{\
    LCDSIM_SetPixelIndexAlpha(x, y, c, LCD_DISPLAY_INDEX, g_AlphaValue);\
}
#endif
[3].在LCDSim.c文件中,增加如下代码, 相应在LCDSim.h中增加如下LCDSIM_SetPixelIndexAlpha()函数的声明:
/*********************************************************************
*       LCDSIM_SetPixelIndexAlpha
*/
//houhh 20061211...
//可参考LCD_MixColors256.c中的LCD_MixColors256()函数.
void LCDSIM_SetPixelIndexAlpha(int x, int y, int Index, int LayerIndex, unsigned Alpha) {
 RETURN_IF_NOT_INITIALIZED(;);
 #ifdef _DEBUG
    _CheckBreak(x, y, LayerIndex);
 #endif
 ASSERT(x >= 0);
 ASSERT(x < _aVXSize[LayerIndex]);
 ASSERT(y >= 0);
 ASSERT(y < _aVYSize[LayerIndex]);
 if (_aBPP[LayerIndex] <= 8) {
    U32 Color2, Color1;
    Color1 = LCD_Index2Color(Index);
    Color2 = LCDSIM_GetPixelColor(x, y, LayerIndex);
    Color1 = LCD_MixColors256( Color2, Color1, Alpha);
    Index = LCD_Color2Index(Color1);
    *XY2PTR(x,y, LayerIndex) = Index;
 } else {
    U32 Index32 = _ColorIndex2COLORREF(Index, LayerIndex);
    Index32 = LCD_MixColors256(LCDSIM_GetPixelColor(x, y, LayerIndex), Index32, Alpha);
    *XY2PTR_DWORD(x, y, LayerIndex) = Index32;
 }
 MARK_MODIFIED(LayerIndex);
}
三.MemDev下实现透明窗体的问题
如果一般窗体创建时指定了WM_CF_MEMDEV属性,则实现透明窗体与上面有很大的不同,下面详细谈谈其原因.
1.首先必须明白,MemDev当中的绘图操作是针对一块分配的内存(对应屏幕一块矩形区域),所以绘图过程中不会对屏幕产生影响(避免了闪烁),只是在绘图完成之后, 然后才将此块内存区域整块的复制到屏幕上,因此用户看到的就是一次屏幕更新,但实际上绘图时是经过多个基本绘图操作组合的.
2.窗体有WM_CF_MEMDEV属性后,则窗体上的绘图操将在内存当中进行,此块区域大小等于窗口大小,当然窗体重绘完成后就将此块区域复制到窗体在屏幕上的区域, 因此的窗体绘制是调用的MemDev当中的基本绘图操作,所以必须更改这些绘图操作,使其支持透明绘制.
3.内存设备当中,支持1/8/16位三种类型(即内存中每个点所占的位数),其中实际显存中象素等于或小于8位的,均在内存当中用八位表示一个点,其实8/16这两种类型是一样的,仅仅是宏定义中的一些数据类型不一样(如定义象素点的数据类型为char或short),所以其代码是共用的.对于单色的情况,没有透明显示,所以我们仅须处理8位的MemDev当中的基本绘图透明支持即可.
4.主要的修改集中在GUIDEV_8.c当中, 分别是_SetPixelIndex()/_FillRect()/_DrawVLine()等几个函数的透明化支持:
_SetPixelIndex()---------绘点.
_FillRect()--------------填充矩形(UCGUI中采取的是GUI_memset()赋值,因此这对于透明支持显然不行,因为透明支持必须逐点处理,取出每个点的颜色来处理,所以如此赋值达不到透明效果,必须更改为逐点画,这样做效率是比较低的).
_DrawVLine()-------------竖直线
_DrawHLine()-------------水平线(调用矩形填充).
_DrawBitmap()------------位图(要处理1/2/4/8/16这几种情况的位图).
[特别注意:_FillRect()在MemDev中的加速处理,与透明化支持相背的,所以必须降低效率变填充为逐点画才行]
5.具体的代码修改.
这里不再详细的说明代码修改,要改的地方已经都在第4点中列出,这时只略提几处改的地方.
[1].增加一个函数,用来将指定内存的点转换成透明处理后的颜色索引.
/*********************************************************************
*       GetAlphaColor
*/
//houhh 20061217...
extern unsigned GetAlpha();
static PIXELINDEX GetAlphaColor(PIXELINDEX* pData, int index)
{
 LCD_COLOR Color1, Color2;
 int Alpha = GetAlpha();
 if(Alpha != 0){
     Color1 = LCD_Index2Color(index);
     Color2 = LCD_Index2Color(*(pData));
     Color2 = LCD_MixColors256(Color1, Color2, Alpha);  
     return (PIXELINDEX)LCD_Color2Index(Color2);
 }
 else
     return index;
}
[2].矩形填充,有一处修改如下:
/* Fill */
/* 2006-12-18 16:21:03
      #if BITSPERPIXEL == 8
        GUI_MEMSET(pData, LCD_COLORINDEX, Len);
      #elif BITSPERPIXEL == 16
        GUI__memset16(pData, LCD_COLORINDEX, Len);
      #else
        #error Unsupported
      #endif*/
       int x = x0;   //houhh 20061218...
       for(; x0 <= x1; x0++){
        pData = _XY2PTR(x0, y0);
        *pData = GetAlphaColor(pData, LCD_COLORINDEX);
       }
       x0 = x;
      
[3].画点函数,仅仅修改了一句,将颜色索引进行透明处理即可, 其它的几个位图函数以及画线函数,基本都是类似这个的修改,仅仅修改一句代码即可.
/*********************************************************************
*       _SetPixelIndex
*/
static void _SetPixelIndex(int x, int y, int Index) {
 GUI_MEMDEV* pDev = GUI_MEMDEV_H2P(GUI_Context.hDevData);
 GUI_USAGE_h hUsage = pDev->hUsage;
 PIXELINDEX* pData = _XY2PTR(x, y);
// *pData = Index;
//houhh 20061217...
 *pData = GetAlphaColor(pData, Index);;
 if (hUsage) {
    GUI_USAGE_AddPixel(GUI_USAGE_H2P(hUsage), x, y);
 }
}
四.透明窗体是否仅绘图时进行透明处理即可?
特别把这一点拿出来单独的讲,是为了更强调这个问题,有些朋友会问,既然如上面所说,将绘图操作进行了透明处理,他们就这样理解:
"窗体的透明设置我觉得可以对cb回调函数中的“WM_PAINT:”进行相应的透明绘图,且不让它填充矩形框及颜色,那它就会显示透明了。"
针对这种想法,可以提出几个问题,如果这几个问题都能回答,那么上面的说明才是可行,否则断不能行, WM_CF_HASTRANS属性必不可少.
[关键词:我们称要实现透明的窗体为WIN_Trans]
1.首先指出一点, 对于没指定WM_CF_HASTRANS属性的WIN_Trans窗体,是可以变成无效窗体,从而在DrawNext()当中调用窗体的重绘的,这与带WM_CF_HASTRANS属性的窗体的重绘是由其它窗体重绘而引发是截然不同的(此时总是在一般窗体绘制之后进行透明窗体绘制).
2.对于非指定WM_CF_HASTRANS属性的WIN_Trans窗体, 进行绘制后如果慢慢拖动窗体的话, 窗体内的原来绘画没有清理将会残留下来,简单的现象就是如果显示一些文字后拖动窗体,可以看到窗体上残留了文字的颜色(这个残留是先前窗体的绘制没被清理, 此残留区域在移动前与移动后还包含在窗体内,所以未被清除而残留).
3.对于非指定WM_CF_HASTRANS属性的WIN_Trans窗体, 当拖动其它窗体与本窗体产生相交的区域后, WIN_Trans窗体会进行重绘, 如果不进行清除操作, 那么就会残留下原来窗体的相交区域(当相交窗体移走后).
4.如果给WIN_Trans窗体加上WM_CF_STAYONTOP属性, 如果其它窗体移动时会看到在WIN_Trans区域内被挡住, 这块区域是WIN_Trans的父窗体的背景色(因为WIN_Trans窗体没有填充背景所至), 这种效果不太符合透明的效果.
5.即使加了WM_CF_STAYONTOP属性,而且在WM_PAINT中绘图进行透明处理,不使用填充矩形框,也是无法实现透明效果的, 依据上面我们所讲的,透明处理是找原来显示屏幕上的一点来进行颜色混合,但是拖动WIN_Trans窗体后,WIN_Trans窗体会在重绘中与自己原来位置的屏幕点进行混合,这样根本不符合透明处理的本质了.
6.因此,UCGUI中实现透明窗体其实是有两个最本质的地方的, 在上面我们已经讲过, 这里再重复如下:
[1].透明窗体在一般窗体之后绘制.
[2].透明窗体的重绘均由其它窗体的重绘而引发,永远不会变成无效窗体(即透明窗体重绘不会由DrawNext()直接调用).
所以UCGUI中的透明窗体,WM_CF_HASTRANS属性是不可少的,WM_CF_STAYONTOP属性是保持透明窗体始终位于前台。
只有上面两点满足了,才可以保证透明窗体最基础的一点:透明窗体每个点绘制时与正确的背景点进行颜色混合(透明化).
五.修改后的代码下载.
所有的文中讲述的修改, 在此提供修改后的代码如下:
1.一般窗体带有WM_CF_MEMDEV属性时的透明窗体支持.
http://www.ucgui.com/ucgui/GUIDEV_8.rar
2.一般窗体无WM_CF_MEMDEV属性时的透明窗体支持.
http://www.ucgui.com/ucgui/LCDWin.rar

UCGUI中的实现透明窗体的原理相关推荐

  1. C#在透明窗体WinForm上面画图(电子尺小工具的实现)

    前几天要做一个微信调一调的外挂,里面用到了尺子测量距离,然后就自己下载了一个电子尺,最近要升级我的跳一跳外挂,然后就准备自己做一个电子尺,嵌入到我的外挂里面,在嵌入到我的外挂之前,我自己做了一个完整版 ...

  2. 01.WPF中制作无边框窗体

    [引用:]http://blog.csdn.net/johnsuna/article/details/1893319 众所周知,在WinForm中,如果要制作一个无边框窗体,可以将窗体的FormBor ...

  3. QT学习笔记(十二):透明窗体设置

    QT学习笔记(十二):透明窗体设置 创建 My_Widget 类 基类为QWidget , My_Widget.cpp 源文件中添加代码 #include "widget.h" # ...

  4. java 透明对话框_java实现jframe透明窗体示例

    java实现jframe透明窗体示例 复制代码 代码如下: import javax.swing.JFrame; public class TansluFrame extends JFrame { p ...

  5. 【转载】Layered Window(分层窗体,透明窗体)

    本文转载自花间醉卧<Layered Window(分层窗体,透明窗体)> // 为窗体添加 WS_EX_LAYERED 属性 , 该属性使窗体支持透明 ModifyStyleEx (0,  ...

  6. WinAPI透明窗体SetLayeredWindowAttributes

    SetLayeredWindowAttributes  BOOL SetLayeredWindowAttributes(                 HWND hwnd,       COLORR ...

  7. WinAPI透明窗体SetLayeredWindowAttributes(转载)

    2019独角兽企业重金招聘Python工程师标准>>> 转载地址(http://hi.baidu.com/qqlt/blog/item/3182fbd35895d7d6a8ec9a7 ...

  8. 【Java面试题】21 Java中的异常处理机制的简单原理和应用。

    [Java面试题]21 Java中的异常处理机制的简单原理和应用. 参考文章: (1)[Java面试题]21 Java中的异常处理机制的简单原理和应用. (2)https://www.cnblogs. ...

  9. 【C 语言】指针间接赋值 ( 直接修改 和 间接修改 指针变量 的值 | 在函数中 间接修改 指针变量 的值 | 在函数中 间接修改 外部变量 的原理 )

    文章目录 一.直接修改 和 间接修改 指针变量 的值 二.在函数中 间接修改 指针变量 的值 三.在函数中 间接修改 外部变量 的原理 一.直接修改 和 间接修改 指针变量 的值 直接修改 指针变量 ...

最新文章

  1. Python全局解释器锁GIL与多线程
  2. [导入]几种流行的AJAX框架jQuery,Mootools,Dojo,Ext JS的对比
  3. 彻底卸载VS 2013
  4. 软件测试工具和报告学习-3月6日
  5. Mysql升级过程的问题
  6. websettings 哪里设置_云浮超级电容用石墨哪里买,可膨胀石墨_青岛天源达
  7. Application Wizard生成的项目文件简介
  8. Hadoop Snappy安装终极教程
  9. 查看Linux内核版本命令
  10. DB2报错原因汇总(sqlcode sqlstate)
  11. 为什么闹钟设置了却不响_苹果手机为什么闹钟设置了却不响
  12. win10总是更新失败
  13. Mockito开发指南
  14. 小啊呜产品读书笔记001:《邱岳的产品手记-05》第9讲 产品案例分析:Hopper的“人工智能” 第10讲 产品被抄袭了怎么办?
  15. boss金服:点买系统的基本解答
  16. cocos shader 之 黑白滤镜
  17. Mac 如何在终端打开文件.md
  18. python是面向对象开发_Python之面向对象
  19. 西南科技大学数电FPGA第一次实验报告
  20. linux安全基线检查内容

热门文章

  1. 【ChatGPT】中国支付清算协会倡议支付行业从业人员谨慎使用ChatGPT
  2. 【UEFI实战】Redfish的BIOS实现1
  3. Linux安装pyhive
  4. 2022年中国互联网行业人才需求趋势:技术类职能占比大,经济发达城人才需求大[图]
  5. 苹果nfc功能怎么开启_苹果连夜开放NFC——雷霆NFC免电源智能锁开启千亿市场
  6. npm与package.json
  7. 定点运算,浮点运算,算术逻辑单元
  8. 中兴网络设备交换机路由器查看告警信息命令方法
  9. 中兴网络设备交换机路由器查看ip状态查看IPv4查看IPv6状态命令方法
  10. wx.getUserProfile调用后没有反应?获取不到真正的用户头像和昵称