Windows系统消息

文章目录

  • Windows系统消息
  • 前言
  • 一、什么是窗口?
  • 二、什么是消息?
    • 消息分类:
    • windows消息机制架构图:
  • 函数说明
    • 消息结构体
    • GetMessage
    • TranslateMessage
    • SendMessage
    • SendMessage/PostMessage的区别
    • 消息循环
    • 消息的接收
  • 代码示例
  • 三、注册窗口消息
    • 消息广播
      • 发送方:
      • 接收方
  • 四、Qt消息机制
    • 图形界面应用程序的消息处理模型
      • Qt中的事件处理
      • 事件的产生
      • Qt中事件的分发
      • 事件的接受和处理
    • Qt平台将系统产生的消息转变成Qt事件
    • qt窗口通信
  • 五、linux下捕获Kill的信号
    • 1.终止进程的一般做法
    • 2.kill 的sigspec的详细内容
    • 3.如何捕捉
    • 例子:

前言

Windows中有一个系统消息队列,对于每一个正在执行的Windows应用程序,系统为其建立一个“消息队列”,即应用程

序消息队列,用来存放该程序可能创建的各种窗口的消息。应用程序中含有一段称作“消息循环”的代码,用来从消息队列中

检索这些消息并把它们分发到相应的窗口函数中。


一、什么是窗口?

在windows中,“一切皆为窗口”。虽然不是很贴切,但是说明了窗口的普遍性和其重要性。比如,你现在看到的QQ聊天窗口,就是由多个窗口组成的!

Windows程序是由一系列的窗口构成的,每个窗口都有自己的窗口过程。

二、什么是消息?

消息就是一组数据包(结构体),用于传递信息。消息可以在操作系统和一个进程之间传递,也可以在两个不同的进程间传递,也可以在同一个进程的不同线程间传递或同一个进程的不同窗口间传递。 比如,你在QQ聊天窗口中点一下鼠标,打字等,都会产生消息。在代码中消息是以消息结构体MSG来保存的,里面的成员包括处理该消息的窗口句柄,消息代码,消息产生的时间和光标的位置等。

消息分类:

<1>.队列消息和非队列消息:从消息的发送途径上看,消息分两种:队列消息和非队列消息。 队列消息送到系统消息队列,然后到线程消息队列;非队列消息直接送给目的窗口过程。这里,对消息队列阐述如下

Windows维护一个系统消息队列(System message queue),每个GUI线程有一个线程消息队列(Thread message queue)。鼠标、键盘事件由鼠标或键盘驱动程序转换成输入消息并把消息放进系统消息队列,例如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR等等。Windows每次从系统消息队列移走一个消息,确定它是送给哪个窗口的和这个窗口是由哪个线程创建的,然后,把它放进窗口创建线程的线程消息队列。线程消息队列接收送给该线程所创建窗口的消息。线程从消息队列取出消息,通过Windows把它送给适当的窗口过程来处理。
  除了键盘、鼠标消息以外,队列消息还有WM_PAINT、WM_TIMER和WM_QUIT。这些队列消息以外的绝大多数消息是非队列消息。
  
<2>统消息和应用程序消息: 从消息的来源来看,可以分为:系统定义的消息和应用程序定义的消息。(控件改变时自己也会向系统发送消息

系统消息ID的范围是从0到WM_USER-1,或0X80000到0XBFFFF;应用程序消息从WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USER到0X7FFF范围的消息由应用程序自己使用;0XC000到0XFFFF范围的消息用来和其他应用程序通信,为了ID的唯一性,使用::RegisterWindowMessage来得到该范围的消息ID。
  
<3>窗口消息,命令消息,控件通知消息:根据处理过程的不同,可以分为三类:窗口消息,命令消息,控件通知消息
(1).窗口消息
一般以WM_开头,如WM_CREATE, WM_SIZE, WM_MOUSEMOVE等标准的Windows消息, 用于窗口相关的事件通知,窗口消息将由系统分配到该窗口的窗口过程处理。
(2).命令消息 (WM_COMMAND)
一种特殊的窗口消息,它从一个窗口发送到另一个窗口以处理来自用户的请求,通常是从子窗口发送到父窗口,例如,点击按钮时,按钮的父窗口会收到WM_COMMAND消息,用以通知父窗口按钮被点击,经测试:子窗口向父窗口发送WM_COMMAND消息,或者称为父窗口会收到WM_COMMAND消息,操作系统并不是通过将WM_COMMAND消息放入到父窗口的消息队列中去,而是直接调用了父窗口的窗口过程,以 WM_COMMAND 为消息标识参数(UINT uMsg),实现这个功能的API函数正是: LRESULT DispatchMessage(const MSG *lpmsg);
(3).控件通知消息
WM_NOTIFY消息,当用户与控件交互(Edit, Button)时,通知消息会从控件窗口发送到父窗口,这种消息的目的不是为了处理用户命令,而是为了让父窗 口能够适时的改变控件。


windows消息机制架构图:

函数说明

消息结构体

MSG 结构体
typedef struct tagMSG {HWND        hwnd;UINT        message;    //消息IDWPARAM      wParam;LPARAM      lParam;DWORD       time;        //时间(消息投递到消息队列的时间)POINT       pt;          //鼠标的当前位置
#ifdef _MACDWORD       lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;

GetMessage

从消息队列中获得消息,并移除,无消息时,等待,,如果得到WM_QUIT消息返回的0,结束循环

原型:

BOOL
WINAPI
GetMessageW(
_Out_ LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax);

TranslateMessage

大小写键盘翻译

例子:

TranslateMessage(&msg);

SendMessage

把消息发送到指定窗口,直接给消息处理函数,直到消息处理函数返回结束,堵塞函数(必须等消息处理完成)
原型:

LRESULT
WINAPI
SendMessageW(
_In_ HWND hWnd,
_In_ UINT Msg,    //消息
_Pre_maybenull_ _Post_valid_ WPARAM wParam,
_Pre_maybenull_ _Post_valid_ LPARAM lParam);

例子:

SendMessage(hWnd, WM_CLOSE, 0, 0);    //WM_DESTROY 是关闭程序的  M_CLOSE 是关闭窗口的     WM_QUIT 是关闭消息环的

SendMessage/PostMessage的区别

SendMessage为同步,PostMessage为异步,GetMessage只处理第一个链表即SentMessagesListHead里面的消息

当一个程序利用SendMessage向另外一个程序发送消息时,另外一个程序会用GetMessage接收,这个过程GetMessage会在0环的SentMessagesListHead链表里面搜索是否存在SendMessage,如果存在SendMessage,GetMessage就会在两个程序的共享内存里面向发送消息的程序发送一个结果,在这个过程中,发送消息的程序是一直处于等待状态的,只有接收到返回的消息才会结束,这称为同步
如果利用PostMessage发送消息,处于第二个链表里面,GetMessage不会处理,而程序发完消息之后也会立即结束,不会有等待的过程,这成为异步,如果要处理,使用DispatchMessage()处理

MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{TranslateMessage(&msg);DispatchMessage(&msg);
}

消息循环

取得的消息将交由窗口处理函数进行处理,对于每个窗口类Windows 为我们预备了一个
默认的窗口过程处理函数DefWindowProc(),这样做的好处是,我们可以着眼于我们感兴趣
的消息,把其他不感兴趣的消息传递给默认窗口过程函数进行处理。每一个窗口类都有一个
窗口过程函数,此函数是一个回调函数,它是由Windows 操作系统负责调用的,而应用程
序本身不能调用它。以switch 语句开始,对于每条感兴趣的消息都以一个case 引出。

LRESULT CALLBACK WndProc
(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
…switch(uMsgId){case WM_TIMER://对WM_TIMER 定时器消息的处理过程return 0;case WM_LBUTTONDOWN://对鼠标左键单击消息的处理过程reurn 0;
. …default:return DefWindowProc(hwnd,uMsgId,wParam,lParam);}
}

对于每条已经处理过的消息都必须返回0,否则消息将不停的重试下去;对于不感兴趣
的消息,交给DefWindowProc()函数进行处理,并需要返回其处理值。

消息的接收

消息队列的结构

<1> SentMessagesListHead //接到SendMessage发来的消息<2> PostedMessagesListHead //接到PostMessage发来的消息<3> HardwareMessagesListHead //接到鼠标、键盘的消息

如果要取所有队列的消息,则第二个参数设置为NULL,后两个参数全部设置为0

GetMessage的主要功能:循环判断是否有该窗口的消息,如果有,将消息存储到MSG指定的结构,并将消息从列表中删除

GetMessage(  LPMSG lpMsg,  //返回从队列中摘下来的消息HWND hWnd,  //过滤条件一:发个这个窗口的消息UNIT wMsgFilterMin, //过滤条件UNIT wMsgFilterMax //过滤条件
);

代码示例

使用vs2010创建的一个windows窗口程序。
代码如下:

#include <windows.h>
#include <iostream>
//包含应用程序中数据类型和数据结构的定义
long CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//窗口说明
// WinMain函数是所有Windows应用程序的入口,类似c语言中的main函数 其功能是完成//一系列的定义和初始化,并产生消息循环
// WinMain函数实现以下功能:注册窗口类,建立窗口及执行其他必要的初始化工作;进入消息循环,根据从应用程序消息队列接受的消息,调用相应的处理过程;当消息循环检
//测到WM_QUIT消息时终止程序运行
// WinMain函数有三个基本部分组成:函数说明、初始化和消息循环*/
//函数说明
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {HWND hwnd;MSG Msg;WNDCLASS wndclass;char lpszClassName[] = "窗口";  //窗口类名char lpszTitle[] = "test";    //窗口标题名//窗口类定义//窗口类定义了窗口的形式与功能 窗口类定义通过给窗口类数据结构WNDCLASS赋值完成//该数据结构中包含窗口类的各种属性wndclass.style = 0;                                              // 窗口类型为缺省类型wndclass.lpfnWndProc = WndProc;                                  //定义窗口处理函数wndclass.cbClsExtra = 0;                                         //窗口类无扩展wndclass.cbWndExtra = 0;                                         //窗口实例无扩展wndclass.hInstance = hInstance;                                  //当前实例句柄wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);                //窗口的最小化图标为缺省图标wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);                  // 窗口采用箭头光标wndclass.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));  //窗口背景为白色wndclass.lpszMenuName = NULL;                                    //窗口无菜单wndclass.lpszClassName = lpszClassName;                          //窗口类名为“窗口”if (!RegisterClass(&wndclass))  {MessageBeep(0);return FALSE;}///创建窗口 创建一个窗口的实例由函数CreateWindow()实现hwnd = CreateWindow(lpszClassName, lpszTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL,hInstance, NULL);//显示窗口ShowWindow(hwnd, nCmdShow);//绘制用户区UpdateWindow(hwnd);//消息循环while (GetMessage(&Msg, NULL, 0, 0)) {TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;  //消息循环结束 即程序结束时 将信息返回系统
}
//窗口函数
//窗口函数定义了应用程序对接收到的不同消息的响应,其中包含了应用程序对各种可能接受到的消息的
//处理过程,是消息处理分支控制语句的集合
long CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {switch (message) {case WM_DESTROY:PostQuitMessage(0);break;case 256:   //WM_KEYUP = 256按下一个键exit(0);break;default:  return DefWindowProc(hwnd, message, wParam, lParam);}return (0);
}

三、注册窗口消息

和其它消息通信的区别:
WM_* 只用于windows预定义的消息,都有特定的含义;
WM_USER+* 只能用于窗口过程(即通信目标必须是窗口类注册的窗口),否则无效;
WM_COPYDATA 是一个特殊的WM_*消息,但只用于同步通信,必须使用SendMessage。
注册消息:比WM_USER+*更灵活,常用于多个进程同时处理统一个消息(注意是进程而不只是窗口)。

消息广播

处于同一台电脑的进程A,要给进程B发数据。但是进程B的主窗口在创建时,没有指定类名,也没有指定窗口名,所以无法通过::FindWindow()来获得窗口句柄,从而发消息。后来解决办法是通过HWND_BROADCAST广播消息。

发送方:

发送一个窗口关闭消息

const UINT WM_WSW_ShowQRCode = ::RegisterWindowMessage(_T("WSW_ShowQRCode_Function"));
PostMessage(HWND_BROADCAST, WM_CLOSE, 0 , 0);

接收方

//首先需要注册一个与之对应的自定义消息
const UINT WM_WSW_ShowQRCode = ::RegisterWindowMessage(_T("WSW_ShowQRCode"));
//消息响应
ON_REGISTERED_MESSAGE(WM_WSW_ShowQRCode, OnShowQRCode_WSW)

总结:HWND_BROADCAST,是对所有通过 RegisterWindowMessage方法注册了同一个消息的窗口,都发送广播(此文中为,对所有注册了WSW_ShowQRCode消息的窗口,都广播)。对于无法获得窗口的句柄时,才采用此方法。

四、Qt消息机制

图形界面应用程序的消息处理模型

特点:
基于操作系统才能运行;
GUI应用程序提供的功能必须由用户触发;
用户操作界面时操作系统是第一个感知的 ;
系统内核的消息通过事件处理转变成QT的信号。

Qt中的事件处理

在Qt中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent. 事件处理的核心包括事件产生、分发、接受和处理。

事件的产生

问题:谁来产生事件?
最容易想到的是我们的输入设备,比如键盘、鼠标产生的keyPressEvent,keyReleaseEvent,mousePressEvent,mouseReleaseEvent事件(他们被封装成QMouseEvent和QKeyEvent)。

Qt中事件的分发

问题:谁来负责分发事件?
对于non-GUI的Qt程序,是由QCoreApplication负责将QEvent分发给QObject的子类-Receiver.;对于Qt GUI程序,由QApplication来负责。

事件的接受和处理

问题:谁来接受和处理事件?
答案是QObject。类是整个Qt对象模型的心脏,事件处理机制是QObject三大职责(内存管理、内省(intropection)与事件处理制)之一。任何一个想要接受并处理事件的对象均须继承自QObject,可以选择重载QObject::event()函数或事件的处理权转给父类。

Qt平台将系统产生的消息转变成Qt事件

A. Qt事件是一个QEvent(或子类)的对象;
B. 有时一个事件包含多个事件类型,比如鼠标事件又可以分为鼠标按下、双击、和移动多种操作事件类型由QEvent类的枚举型QEvent::Type来表示,可由帮助文档进行查询;
C. Qt事件用于描述程序内部或外部发生的对应动作(描述的是操作系统发生来的消息,一个系统消息对应着一个消息事件);
D. 任意QObject对象都具备时间处理的能力.


Qt 程序需要在main()函数创建一个QApplication对象,然后调用它的exec()函数。这个函数就是开始 Qt 的事件循环。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件。当事件发生时,Qt 将创建一个事件对象。Qt 中所有事件类都继承于QEvent。在事件对象创建完毕后,Qt 将这个事件对象传递给QObject的event()函数。event()函数并不直接处理事件,而是将这些事件对象按照它们不同的类型,分发给不同的事件处理器(event handler)。如上所述,event()函数主要用于事件的分发。

qt窗口通信

  • Qt4版本的实现

方法1:

// 通过继承QWidget的类中重新实现winEvent接口,以接收在消息参数中传递的本机Windows事件。
bool QWidget::winEvent(MSG *message, long *result)

方法2:

// 通过继承QCoreApplication的类中重新实现winEventFilter接口,以接收在消息参数中传递的本机Windows事件。
bool QCoreApplication::winEventFilter(MSG *msg, long *result)
  • Qt5版本实现

方法1:

// 通过继承QWidget的类中重新实现winEvent接口,以接收在消息参数中传递的eventType标识的本机平台事件。
bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)

方法2:

// 通过继承QAbstractNativeEventFilter的类中重新实现nativeEventFilter接口:
bool QAbstractNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)

并安装到中:

void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)

或安装到:

void QAbstractEventDispatcher::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)

特别地:不同平台对应的eventType类型有:
平台 事件类型(eventType) 消息类型(message) 结果类型(result)
Windows “windows_generic_MSG” MSG * LRESULT
macOs “NSEvent” NSEvent * 无
XCB(Linux) “xcb_generic_event_t” xcb_generic_event_t * 无

// 继承Qt的基类QAbstractNativeEventFilterclass HHNativeEventFilter : public QAbstractNativeEventFilter
{
protected:bool nativeEventFilter(const QByteArray &eventType, void *message, long *){if (eventType == "windows_generic_MSG"|| eventType == "windows_dispatcher_MSG"){PMSG msg = static_cast<PMSG>(message);if(msg->message == WM_CLOSE ){qApp->exit();}}return false;}
};
// 利用QApplication注册类对象
app.installNativeEventFilter(new NativeEventFilter);

五、linux下捕获Kill的信号

1.终止进程的一般做法

在运行程序时要对某些程序进程进行终止操作,可以使用kill命令和对应的pid号进行处理,这种方法对于后台运行的程序特别有用:
ps -a 列出所有进程:

  PID TTY          TIME CMD3946 pts/20   00:23:11 python3523 pts/27   00:10:00 ps

或者使用管道来获取对应应用程序的进程号:

ps | grep python
3946 pts/20 00:13:55 python

随后就可以使用kill来关闭这一程序了:

kill -9 2946

但是,kill命令除了-9外还有很多的用途:

kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

2.kill 的sigspec的详细内容

在终端中输入kill -l会看到除了-9外还有很多其他的信号:

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

其中9是立即结束进程的信号不能被阻塞处理,而安全结束进程的信号可以使用SIGTERM(15),这个信号可以被阻塞处理。
需要注意的是:
默认情况下, kill或pkill命令发送的信号是SIGTERM(15) 。
kill -9或pkill -9将发送SIGKILL信号。 不能捕获或忽略 SIGKILL或SIGSTOP信号。
常用的Ctrl+C 发出的是SIGKILL信号。

3.如何捕捉

    signal 函数比较老了,功能有一些限制,现在常用的是 sigaction, 仅在信号处理程序中使用异步信号安全的函数。
// 第一个参数为目标信号,第二个参数为sigaction结构,内有处理机制,信号掩码,和标志
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include <signal.h>
#include <unistd.h>#define SIGTERM_MSG "SIGTERM received.\n"void sig_term_handler(int signum, siginfo_t *info, void *ptr)
{write(STDERR_FILENO, SIGTERM_MSG, sizeof(SIGTERM_MSG));
}void catch_sigterm()
{static struct sigaction _sigact;memset(&_sigact, 0, sizeof(_sigact));_sigact.sa_sigaction = sig_term_handler;_sigact.sa_flags = SA_SIGINFO;sigaction(SIGTERM, &_sigact, NULL);
}void main()
{catch_sigterm();printf("I am sleeping...\n");sleep(3000);
}

【C/C++ Windows编程】Windows系统消息、Qt消息事件、linux下kill信号相关推荐

  1. Windows编程—Windows驱动中定时器的使用

    文章目录 Windows编程-Windows驱动中定时器的使用 前言 代码 简单版 升级版 程序效果 Windows编程-Windows驱动中定时器的使用 前言 定时器操作是应用编程中非常常见的操作, ...

  2. QT消息/事件循环机制与多线程的关系

    关于Qt子线程和消息循环 一.QT消息/事件循环机制 Qt作为一个可视化GUI界面操作系统,是基于事件驱动的,我们程序执行的顺序不再是线性,而是由一个个应用程序内部或外部的事件进行驱动,无事件时便阻塞 ...

  3. 在linux下从firefox导入windows的收藏夹,1、Ubuntu linux下同步windows火狐foxfire 浏览器收藏夹问题...

    最近在ubuntu系统中使用自带的firefox浏览器,发现有一些问题,比如登陆后,书签,历史记录等,原本在windows下同步的数据无法同步,添加书签的功能也无法使用. 经过查询资料后得知,unbu ...

  4. C++(Qt)软件调试---linux下生成/调试Core文件(3)

    #软件调试 C++(Qt)软件调试-linux下生成/调试Core文件(3) 文章目录 C++(Qt)软件调试---linux下生成/调试Core文件(3) 前言 1.C++生成Core和使用GDB调 ...

  5. Windows编程—Windows驱动开发环境搭建

    文章目录 前言 步骤 步骤一 步骤二 步骤三 连接测试 步骤四 步骤五 总结 前言 作为一个编写Windows程序的开发人员,对Windows驱动开发 并非必需要掌握,但是掌握 Windows驱动开发 ...

  6. pip install安装系列之Pytorch、TorchVision、PyQt、OpenCV、gdcm包安装,Windows远程桌面Ubuntu16.04记录,Linux下安装google浏览器汇总

    目录 1.Anaconda各版本下载地址 2.Torch,Torchvision 3.PyQt4/5,OpenCV的安装 4.win10安装tensorflow 5.Windows7远程桌面Ubunt ...

  7. 【网络编程入门】使用socket在Linux下实现即时通信软件

    使用socket在Linux下实现即时通信软件 在前一篇文章中讲到了如何使用winsock:[网络编程入门]在C++中使用Windows TCP Sockets,也算是勉强入门了吧,接下来自己写一下在 ...

  8. qt程序在Linux下字体乱了,解决linux/Ubuntu下Qt creater 界面程序在编译运行后无法显示中文或中文乱码问题!...

    本文解决的主要是界面程序编译运行后无法显示中文的问题,如果在creater 中无法输入中文,下载个IBus或者搜狗之类的中文输入法即可解决! 首先说乱码问题,这个很好解决: 如果是在linux下打开W ...

  9. Hello Qt(在Linux下编写运行Qt程序)

    From: http://www.yafeilinux.com/?p=763 <一>Hello Qt小试牛刀! 说明:我们需要在Linux下已经安装了Qt. 1.下面是整个程序的详细介绍: ...

最新文章

  1. mysql中查询表格属性
  2. 云计算是数据分析的最佳场所吗?
  3. 在GridView中针对鼠标单击的某一独立单元格进行编辑
  4. 【DA算法】基于DA算法的FIR滤波器的FPGA实现
  5. 机房布线的最高境界......
  6. SmartUpload文件上传组件的使用教程
  7. CCNA-第十六篇-综合实验
  8. MessageBox消息框 1126
  9. ftp ---- 匿名用户(实例配置示例1:匿名用户登录)
  10. android canvas 工作流_行情艰难,Android初中级面试题助你逆风翻盘,每题都有详细答案...
  11. 关于python的浮点数类型、以下_python入门教程Python 浮点数数据类型详解 [学习 Python 必备基础知识][看此一篇就够了]...
  12. 【机器学习】选择模型
  13. ElementUI:vue中使用elementUI时候通过SCSS修改NavMenu 导航栏高度
  14. Java开发使用百度翻译api
  15. 锐起无盘服务器只能是什么系统,安装锐起无盘客户机系统要注意什么
  16. 移动端适配,华为浏览器底色无法正常显示
  17. 破解数字化转型难题,华为云一站式大数据BI赋能企业发展
  18. 电脑桌面计算机文件打不开怎么办,教大家电脑桌面上的文件都打不开怎么办
  19. 你是如何进行文件备份的?
  20. oracle maxidletime,ORA-02396:超过最大空闲时间,请再次连接

热门文章

  1. Python中[m: ]、[ :n]、[m:n]、[m::n]的含义
  2. 记录通过台词搜索电影的工具
  3. 硬科技的时代之路,镁客网与你一起见证!
  4. MP3音频录音机6.30版
  5. Azure Data Factory操作使用介绍
  6. php八字喜用神实现博客,八字喜用神分析你是什么性格
  7. 供货理想等近20家主流车企,移远通信5G车载模组交付量大幅增长
  8. 硕士生如何选择三维扫描研究课题? 实例一:将多层扫描服装模型“穿”到人体模型上
  9. 《软件研制任务书》的正文格式
  10. Linux C/C++ 学习路线(已拿腾讯、百度 offer)2