EVC开发实例:窗口切换
- 格式:pdf
- 大小:152.85 KB
- 文档页数:4
1.EVC工程转换为VS2005(或VS2008)EVC工程转换为VS2005或者VS2008工程后,一般要经过修改后才能编译成功,对于本光盘提供的例程,用户只需要简单的修改便可以使用。
方法是使用VS2005/VS2008打开“xx.VCP”工作区文件,自动转换后,然后编译,修改错误,检查,修改,完成!1.1.转换示例“TestCan”工程先准备好硬件,WinCE设置要上电,并且与PC机使用USB Device线同步上。
软件:选中“TestCan.vcp”,使用VS2005(或VS2008)打开。
注意必须是vcp文件。
点击“完成”。
再点击“关闭”。
上图中选择正确的SDK。
然后编译。
编译错误如下:直接将“ #include "wceres.rc" ”注释掉。
再点击下图中“绿色三角”。
发现可以编译通过。
WinCE上程序跑起来了。
发现有乱码。
原来“Combo Box”控件的初始数据值不正常。
参考原来EVC编译出来的程序。
把“Combo Box”控件的属性修改过来。
修改后重新运行。
如果编译出错,此时有可能要重新将“ #include "wceres.rc" ”注释掉。
直到问题解决。
转换完成。
注意关闭工程后提示保存“x.sln”文件,请保存在工程目录即可。
2.EVC工程转换为VS2005(或VS2008)常见错误与解决下面内容来源于网上,仅供参考。
资源文件乱码错误:最重要的Menu Bar的转化。
在eVC4里是没有RC2文件的,Menu Bar的定义是在RC文件中的,而在VS2005中把Menu Bar的定义放到了RC2文件中,如果不把这部分放到RC2中,VS2005会把定义中的宏变成十六进制,让人看不懂,但是功能具备。
IDR_MENU SHMENUBAR MOVEABLE PUREBEGINIDR_MENU, 2,I_IMAGENONE, IDM_DONE, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE, IDS_OK, 0,NOMENU,I_IMAGENONE, IDM_OPTIONS, TBSTATE_ENABLED,TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_HELP, 0, 1,END如果在VS2005中,改变资源然后保存资源。
Objective-C页面跳转方法总结在iOS开发中,页面跳转是一个非常常见的需求。
无论是用于用户导航,还是用于实现不同模块之间的跳转,页面跳转都是不可或缺的功能。
在Objective-C中,有多种方式可以实现页面跳转,每种方式都有其适用的场景和特点。
在本文中,我将对Objective-C中常见的页面跳转方法进行总结,旨在帮助读者更全面、深刻地理解这一主题。
1. 使用NavigationController进行页面跳转在iOS开发中,使用NavigationController进行页面跳转是一种非常常见的方式。
在Objective-C中,我们可以通过创建NavigationController,并将需要跳转的ViewController添加到其导航栈中来实现页面跳转。
这种方式适用于需要实现层级导航的场景,比如导航栏、返回按钮等。
2. 使用PresentViewController进行页面跳转除了NavigationController,我们还可以使用PresentViewController方法来实现页面跳转。
这种方式适用于需要模态展示新页面的场景,比如弹出登录框、展示详情页面等。
通过PresentViewController方法,我们可以将需要跳转的ViewController以模态的方式展示在当前页面上。
3. 使用TabBarController进行页面跳转如果我们的应用需要实现底部栏切换不同模块的功能,那么可以使用TabBarController进行页面跳转。
在Objective-C中,我们可以通过创建TabBarController,并将需要跳转的ViewController添加到其TabBar中来实现页面间的切换。
这种方式适用于需要快速切换不同模块的场景,比如主页、发现页、个人中心等。
4. 使用Segue进行页面跳转在Storyboard中,我们可以使用Segue进行页面跳转。
通过在Storyboard中创建Segue,并在代码中触发Segue来实现页面之间的跳转。
VC怎样设置控制台窗口界面一、概述所谓控制台应用程序,就是指那些需要与传统DOS操作系统保持某种程序的兼容,同时又不需要为用户提供完善界面的程序。
简单地讲,就是指在Windows环境下运行的DOS程序。
一旦C++控制台应用程序在Windows 9x/NT/2000操作系统中运行后,就会弹出一个窗口。
例如下列过程:单击Visual C++标准工具栏上的“New Text File”按钮,打开一个新的文档窗口。
选择File | Save菜单或按快捷键Ctrl+S或单击标准工具栏的Save 按钮,弹出“保存为”文件对话框。
将文件名为“Hello.cpp” (注意扩展名.cpp 不能省略)。
在文档窗口中输入下列代码:#include<iostream.h>{cout<<"Hello, Console!"<<endl;}单击小型编译工具栏中的“Build”按钮或按F7键,系统出现一个对话框,询问是否将此项目的工作文件夹设定源文件所在的文件夹,单击[是]按钮,系统开始编译。
单击小型编译工具栏中的“Execute Program”按钮或按Ctrl+F5键,运行刚才的程序。
程序运行后,弹出下图的窗口。
这就是控制台窗口,与传统的DOS屏幕窗口相比最主要的区别有:(1) 默认的控制台窗口有系统菜单和标题,它是一个内存缓冲区窗口,缓冲区大小取决于Windows操作系统的分配;而DOS屏幕是一种物理窗口,不具有Windows窗口特性,其大小取决于ROM BIOS分配的内存空间。
(2) 控制台窗口的文本操作是调用低层的Win32 APIs,而DOS屏幕的文本操作是通过调用BIOS的16(10h)中断而实现的。
(3) 默认的控制台窗口可以接收键盘和鼠标的输入信息,设备驱动由Windows管理,而DOS屏幕窗口接收鼠标时需要调用33h中断,且鼠标设备驱动程序由自己安装。
C#学习及上位机开发学习之多窗⼝切换多窗⼝切换【功能⽬标】1、实现多窗⼝切换(Panel)2、动态⽣成窗⼝内⽂本框以及标签(重点)3、改变⽂本框内容【效果图】【代码详解】1、多窗⼝切换如要实现多窗⼝切换,需要⽤到Panel,对于这个控件不熟悉的可以看我上⼀篇介绍;Panel是容器控件,我们需要把这些页⾯的控件分别放⼊四个容器中,每个容器开始都设计为不显⽰属性(Visible = false);当点击按钮时切换页⾯,改变显⽰属性;如下代码所⽰当前有四个容器group_voltage、group_soc、group_soh、group_fujiaprivate void Btn_Volatage_Click(object sender, EventArgs e){//电压显⽰State_Show = 0;group_voltage.Visible = true;group_soc.Visible = false;group_soh.Visible = false;group_fujia.Visible = false;}private void Btn_SOC_Click(object sender, EventArgs e){//SOC显⽰State_Show = 1;group_voltage.Visible = false;group_soc.Visible = true;group_soh.Visible = false;group_fujia.Visible = false;//this.group_soc.BringToFront();}private void Btn_SOH_Click(object sender, EventArgs e){State_Show = 2;group_voltage.Visible = false;group_soc.Visible = false;group_soh.Visible = true;group_fujia.Visible = false;}private void Btn_ADD_Click(object sender, EventArgs e){State_Show = 3;group_voltage.Visible = false;group_soc.Visible = false;group_soh.Visible = false ;group_fujia.Visible = true;group_fujia.Visible = true;}2、动态⽣成⽂本框数组利⽤⼀个循环,不断声明,在每个循环中,⾸先先声明⼀个控件类,然后修改她的名字(也就是ID),再者修改它的TEXT,长度,宽度。
electron窗⼝相关操作(放⼤缩⼩退出,可拖动,可resize等)如下是对窗⼝最⼤化,最⼩化等相关操作:import { ipcMain, ipcRenderer, remote } from 'electron'import is from 'electron-is'// ipc 通信发送的窗⼝状态改变事件的channel名称export const windowStateChangeChannel = 'window-state-changed'// window的当前状态export const WINDOW_STATE = {FULLSCREEN: 'full-screen',MAXIMIZED: 'maximized',MINIMIZED: 'minimized',HIDDEN: 'hidden',NORMAL: 'normal',}// window可执⾏的操作,通过发送消息触发const windowAction = {maximize: 'window-maximize',unmaximize: 'window-unmaximize',minimize: 'window-minimize',close: 'window-close',}/*** 获取window的状态* @param {window对象} window*/export function getWindowState(window) {if (window.isFullScreen()) {return WINDOW_STATE.FULLSCREEN} if (window.isMaximized()) {return WINDOW_STATE.MAXIMIZED} if (window.isMinimized()) {return WINDOW_STATE.MINIMIZED} if (!window.isVisible()) {return WINDOW_STATE.HIDDEN}return WINDOW_STATE.NORMAL}/*** 发送⼀个 window-state-changed 消息到 renderer 进程* @param {\*} window* @param {\*} state*/function sendWindowStateEvent(window, state) {window.webContents.send(windowStateChangeChannel, state)}/*** 注册 window 状态变化后事件,它会发送⼀个消息到 renderer 进程* @param {window对象} window*/export function registerWindowStateChangedEvents(window) {window.on('enter-full-screen', () => sendWindowStateEvent(window, 'full-screen'))window.on('leave-full-screen', () => sendWindowStateEvent(window, 'normal'))window.on('maximize', () => sendWindowStateEvent(window, 'maximized'))window.on('minimize', () => sendWindowStateEvent(window, 'minimized'))window.on('unmaximize', () => sendWindowStateEvent(window, 'normal'))window.on('restore', () => sendWindowStateEvent(window, 'normal'))window.on('hide', () => sendWindowStateEvent(window, 'hidden'))window.on('show', () => sendWindowStateEvent(window, 'normal'))}/*** 注册 window 状态变化动作,使⽤ ipc.send 对应的消息触发** @param {window对象} window*/export function registerWindowStateChangeActions(window) {// 窗⼝最⼩化ipcMain.on(windowAction.minimize, () => {window.minimize()})// 窗⼝最⼤化ipcMain.on(windowAction.maximize, () => {window.maximize()})// 窗⼝取消最⼤化ipcMain.on(windowAction.unmaximize, () => {window.unmaximize()})// 窗⼝关闭ipcMain.on(windowAction.close, () => {window.close()})}/*** ⽣成带有promise的操作窗⼝的函数,可以进⼀步处理事件结束后的逻辑* @param {窗⼝可执⾏的操作} windowAction*/function generatePromisedWindowStateFunc(action) {return () => {return new Promise((resolve) => {ipcRenderer.send(action)ipcRenderer.once(windowStateChangeChannel, (event, args) => {resolve(args)})})}}/*** ⽣成不带有promise的操作窗⼝函数,只负责触发事件* @param {窗⼝可执⾏的操作} windowAction*/function generateWindowStateFunc(action) {return () => {ipcRenderer.send(action)}}/*** 最⼤化窗⼝的⽅法,因为windows和macOS之间的差异,单独写成⼀个函数 */function handleMaximizeWindow() {if (is.windows()) {remote.getCurrentWindow().maximize()return Promise.resolve(WINDOW_STATE.MAXIMIZED)}return new Promise((resolve) => {ipcRenderer.send(windowAction.maximize)ipcRenderer.once(windowStateChangeChannel, (event, args) => {resolve(args)})})}/*** 窗⼝操作⽅法,包括最⼤化,最⼩化,关闭* 每个⽅法返回⼀个promise,⽅便处理后续逻辑*/export const windowStateActionResponse = {maximize: handleMaximizeWindow,unmaximize: generatePromisedWindowStateFunc(windowAction.unmaximize), minimize: generatePromisedWindowStateFunc(windowAction.minimize),close: generatePromisedWindowStateFunc(windowAction.close),}/*** 窗⼝操作⽅法,包括最⼤化,最⼩化,关闭* 只发送消息,不处理成功之后的回调*/export const WindowStateAction = {maximize: generateWindowStateFunc(windowAction.maximize),unmaximize: generateWindowStateFunc(windowAction.unmaximize),minimize: generateWindowStateFunc(windowAction.minimize),close: generateWindowStateFunc(windowAction.close),}/*** 给窗⼝改变事件增加监听* @param {事件触发后的回调} handle*/export function listenToWindowStateChange(handle) {ipcRenderer.on(windowStateChangeChannel, handle)return () => {ipcRenderer.removeListener(windowStateChangeChannel, handle) }}下⾯是electron配置:import { BrowserWindow, screen } from 'electron'function createWebRTCInternalWindow() {const displayWorkAreaSize = screen.getAllDisplays()[0].workArea const options = {x: displayWorkAreaSize.x,y: displayWorkAreaSize.y,width: displayWorkAreaSize.width,height: displayWorkAreaSize.height,resizable: true,movable: true,fullscreenable: false,enableLargerThanScreen: false,frame: true,transparent: false,alwaysOnTop: false,hasShadow: false,minWidth: 1000,minHeight: 648,webPreferences: {devTools: true,webSecurity: false,plugins: true,experimentalFeatures: true,experimentalCanvasFeatures: true,minimumFontSize: 10,},}const mainWindow = new BrowserWindow(options)return mainWindow}export default createWebRTCInternalWindowimport { BrowserWindow, screen } from 'electron'function createBrowserWindow() {const displayWorkAreaSize = screen.getAllDisplays()[0].workArea const options = {width: parseInt(displayWorkAreaSize.width * 0.85, 10),height: parseInt(displayWorkAreaSize.height * 0.85, 10),center: true,resizable: true,movable: true,fullscreenable: false,enableLargerThanScreen: false,frame: false,transparent: true,alwaysOnTop: false,clickThrough: 'pointer-events',acceptFirstMouse: true,hasShadow: false,minWidth: 1000,minHeight: 648,webPreferences: {devTools: true,webSecurity: false,plugins: true,experimentalFeatures: true,experimentalCanvasFeatures: true,minimumFontSize: 10,},}const mainWindow = new BrowserWindow(options)return mainWindow}export default createBrowserWindow如上配置中可设置⼀系列初始值,其中包括是否可resize,是否可拖动等。
初识Embedded Visual C++作者:付林林大家一定会对W indows CE 操作系统有所耳闻,它是微软已推出的三种操作系统内核之一,是一种实时操作系统。
虽然它是一种实时操作系统,但是从96年发布v1.0到现在,它的主要用途都在民用领域,比如Pocket PC、SmartPhone、Automation。
不像VxWorks,应用于航空航天、军事等领域。
现在linux、VxW orks厂商也都看好嵌入式民用市场,激烈竞争在所难免。
我看好W indows CE,因为微软在PC领域实在太强,用户也早已熟悉了微软的产品,把PC下的技术移植到嵌入式领域,首先在操作界面方面就占了上风。
我有幸在两年前从事W indows CE下内核定制和软件开发工作,做的项目是AutoPC。
入门也不算很难,当初VC++的水平也算凑合了,所以学EVC(embedded v isual c++)也比较快。
做了一些软件后,又开始学习platform builder――定制内核工具。
因为我们的内核是需要自己定制的,不同于Pocket PC、SmartPhone。
未来几年在W indows CE下开发软件的需求将越来越多,我希望有兴趣的程序员能投身其中,开始程序人生新的起点。
如果有时间我将在这个专栏陆续写一些关于EVC的文章,希望能够抛砖引玉。
而关于platform bu ilder的文章,如果有时间我将在中文MSDN网站上发表。
EVC是W indows CE下软件开发工具之一,还有一个EVB,用jav a也可以。
EVB不用说,编译出的软件肯定相对较慢。
jav a也不是什么地方都能用,要看平台是否支持。
所以我认为EVC是首选开发工具。
熟悉VC的程序员要学EVC比较容易,EVC的界面和VC差不多,同样支持SDK、MFC、ATL,所以直接就能上手编写代码。
但需注意的事项也不少,而且要编写和系统底层有关的程序,就必须先了解W indows CE的特征,建议你先学习《W indows 核心编程》,然后再看看W indows CE的帮助文档,了解CE的操作系统特征。
以下由IC人才网整理随着嵌入式CPU的快速发展和RAM的降价,在Windows CE下实现多个程序同时运行也是可行的。
而且运行速度也可以接受。
我们公司的产品就能够一边上网,一边听mp3。
使用起来真的很爽。
假如我们要做一个产品,需要同时运行多个程序,这就涉及到窗口切换的问题。
Windows CE 自带了资源管理器explorer.exe作为外壳程序。
它有窗口切换的功能。
但是绝大多数基于Windows CE的产品都不可能用这个程序做主界面。
原因之一,它的界面和PC下资源管理器一样(也就是桌面),不符合我们这个产品的整体界面风格。
可能我的所有应用程序的界面风格都很好,很漂亮,但主界面,既资源管理器的界面和其它所有程序界面风格不相符,那样太糟糕了。
而且总用同一个界面,用户迟晚会烦的。
原因之二,它将所有资源管理功能都暴露给用户,那样太危险。
用户肆意更改资源设置很容易造成设备损坏或无法启动,一旦无法启动,用户一定会来找你维修,但是你很冤。
所以我们必须自己做一个主操作界面(也就是一个应用程序,或者称为外壳程序)。
这样既可以设计实现自己理想的界面风格,又可以限制留给用户操作的功能。
这个想法虽然好,但是如果允许同时运行多个程序,就必须先解决窗口切换问题。
好在Windows CE 的API和PC下的差不多,实现也不算难。
其实难的是如何把自定义的程序作为外壳程序,替换原来标准的程序。
注:Windows CE允许同时打开最多32个进程,这包括Windows CE启动时系统程序。
注:以后称主操作界面程序为自定义外壳程序。
一、添加自定义外壳原来打算不讲解PB方面的知识,但是在Windows CE下开发,PB和EVC关系紧密,必须两个都懂,才能做出理想的产品。
所以在这里我简单说说PB和CE方面的知识。
1、PB是用于定制操作系统内核的工具,可以把它看成是一个IDE,集成了编辑器(可以编辑源码、注册表等)、编译器(编译操作系统内核、编译某一个模块)、各种向导(生成新内核向导、生成BSP向导、SDK导出向导、组件特征导出向导)、内核调试工具集合、x86模拟器、支持添加或删除组件等。
通常情况下,通过PB来添加、删除组件,每个组件对应一个特定的功能。
假如你希望你的产品具有上网功能,那你就添加某一种网络连接组件和浏览器组件。
假如希望你的产品具有永久存储功能,那你就添加支持永久存储设备的组件,再添加支持某一种文件系统的组件。
设置完毕后,编译整个内核。
最后PB将编译后的所有功能模块组合在一起,形成一个.bin文件,默认为nk.bin。
2、nk.bin包含了你定义的Windows CE内核的全部。
在设备启动时需要解压nk.bin并且将一些系统模块(DLL、EXE)加载到内存中。
用于做解压和加载工作的程序,称为引导程序,可以放在ROM中,也可以放在永久存储设备中。
当设备启动时先检测硬件,再加载引导程序,引导程序解压nk.bin,再把系统模块加载到特定内存区域中,然后将CPU交给CE内核。
3、当你安装完Windows (Windows 安装分为三部分。
分别安装PB、Platform manager、SDK)后,大部分功能模块的源码被复制到安装目录下。
你可以修改这些源码,然后重新编译。
这些源码为OEM提供了更广阔的开发空间。
也是Windows CE比其它Windows操作系统更适合研究的原因。
4、修改源码不是简单的事。
使用PB开发一个内核很少需要修改源码,更多的工作是添加组件、添加文件、修改注册表数据、添加环境变量等。
要添加自定义外壳,涉及到修改注册表和添加文件两个工作。
下面讲具体操作方法:以下假设你已经利用生成内核向导建立了一个内核工程。
1、修改注册表:Windows CE启动时分别执行[HKEY_LOCAL_MACHINE\init]键下所有子键列出的程序。
例如:[HKEY_LOCAL_MACHINE\init]"Launch20"="device.exe""Launch30"="gwes.exe""Depend30"=hex:14,00内核启动时执行device.exe和gwes.exe 。
“LaunchXX”中的XX为序列数,内核依据这个序列数按由小到大的顺序来分别执行所有子键列出的应用程序。
“DependXX”为“LaunchXX”的附属键,此键键值表示“LaunchXX”指定的程序需要依靠哪个程序才能启动。
例如“Depend30”=hex:14,00 。
十六进制数14等于十进制数20,既gwes.exe需要device.exe先启动后才能启动。
因为自定义外壳程序是最后启动的,所以你可以在你的平台选择一个最大的序列数,比如80,然后在common.reg中“[HKEY_LOCAL_MACHINE\init]”键下添加如下格式:"Launch80"="CustomShell.exe" ///自定义的外壳程序,名为CustomShell.exe"Depend80"=hex:14,00,1E,00 ///依靠gwes.exe 和device.exe添加后千万别忘了把原来默认的标准外壳组件从你的内核中删除,找到“Shell and User Interface-Shell-Standard Shell”,单击鼠标右键,再单机“delete”。
当然,你也可以把其它外壳程序都删除。
修改注册表工作到此结束。
2、添加自定义外壳程序:只要允许多个程序同时运行,必然涉及到窗口切换问题,但不同的产品所采取的窗口切换解决方案也不一样。
假如你的产品携带标准键盘,那你可以注册一个或几个热键,当热键按下时,启动窗口切换程序,然后选择你要操作的窗口,然后窗口在最上层显示。
这比较像Windows下任务管理器。
如果你的产品没有携带标准键盘,而是几个按钮,那可以通过串口通讯方式或其它通讯方式解决,当按下按钮时,通过串口发送消息给系统,系统启动窗口切换程序。
如果你的产品在外观上没有键盘,也没有任何按钮,那就必须做一个窗口,像任务栏一样,让它时刻保持在所有窗口最上层,以便响应用户操作。
具体方法你自己选。
我假设现在你用EVC已经把自定义外壳程序做完了。
接着要做的是如何将自定义外壳程序放入内核中,也就是nk.bin里。
从上述“修改注册表”中你会发现,要启动的程序都只有文件名,而没有路径名,这是因为CE只允许把启动程序放到nk.bin中,nk.bin中的所有文件在CE 系统启动后被放在目录\Windows 中。
这一步要做的就是把已经做好的自定义外壳程序放入nk.bin中。
先把编译完的程序CustomShell.exe复制到内核工程目录下。
假设你的内核名为ABC,内核工程所在路径为C:\ABC,采用CPU为National Geode。
那么就复制到“C:\ABC\RelDir\NATIONAL_GEODE_X86Release”目录中。
接着在project.bib中添加下列格式:CustomShell.exe $(_FLATRELEASEDIR)\CustomShell.exe NK这表示在PB编译内核时将CustomShell.exe加入到nk.bin中,并且在CE内核加载时将CustomShell.exe放入内存的系统区域中,内核启动后在\windows目录下可以看到这个文件。
添加自定义外壳程序工作到此结束。
3、编译内核现在编译前期工作已经完成,单击“Build Platform”或“Rebuild Platform”开始编译。
编译前相关设置在此不再多说。
启动CE内核后就可以看到自己设计的外壳程序了。
二、实现窗口切换图片无法复制,如有需要请参考飞凌官网:/news/Article_Show.asp?ArticleID=190图1 假想的任务管理器界面一个简单的窗口切换实例。
打开此程序时,显示所有窗口(不包含隐藏窗口),单击某一个窗口名称,再单击“切换”按钮,相应的窗口出现在Z轴最上层。
在这里我只给出了部分重要的代码。
此处假设工程名为WndList。
///全局函数和全局变量HWND g_hWndArray[50]; //存所有窗口句柄CString g_strArray[50]; //存所有窗口标题int g_iWndCount = 0; //计数器BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lparam){CWnd* pWnd = CWnd::FromHandle(hWnd);if(hWnd != NULL && pWnd->IsWindowVisible()){pWnd->GetWindowText(g_strArray[g_iWndCount]);if((!g_strArray[g_iWndCount].IsEmpty())&& (g_strArray[g_iWndCount].CompareNoCase(L"Desktop") != 0)){g_hWndArray[g_iWndCount] = hWnd; //保存句柄g_iWndCount++;}}return TRUE;}BOOL CWndList::OnInitDialog(){::EnumWindows((WNDENUMPROC)EnumWindowsProc, 0); /////查找所有窗口////创建大字体并加入到列表对象中////将所有窗口句柄加入到列表中}///相应“切换”按钮void CWndList::OnOK(){::SetForegroundWindow(g_hWndArray[m_List.GetCurSel()]); //m_List为列表对象}。