我很郁闷,有一个酷爱CF的男朋友,几次分手都不成功,每一次很我约好出去玩都找不到他,最后都是在网吧打CF。男生怎么可以这样的说话不算数,如果CF更重要,可是为什么他又不放弃我呢?
发表时间:2009-12-05 14:19:33
第一次离楼主这么近......
当然是分了,他觉得游戏都比你重要。。
我男人也老是这样,习惯就好了
我男人也老是这样,习惯就好了
我男人也老是这样,习惯就好了
汗,卡出这么多,我不是故意刷楼的
是他这样,不是男生这样!把话说清楚!LZ脑袋没短路哇?
让你男友跟哥来打打CF...我保证他会离开
分手````我支持你!~~~~~~
我的签名档
前十不容易`````````
我的签名档
我男友也这样
没少因为这个跟他生气 打CF充钱的时候叫我老婆了 充完钱就不是他了
我的签名档
我也觉得他觉得游戏比我重要
我的签名档
事实证明、我也很爱CF、你要滚就滚、别那么墨迹、
让他选一个,不行就分
我惭愧,我也十分喜欢玩这个游戏,玩起来就讨厌别人烦我……老婆来***就说在洗澡……嘿嘿。以后要改了。
怯怯的问一句:CF是什么?。。。。从不玩网游的飘过。。。
分!你男友脑残!玩这弱智游戏!CSER留
14楼如果真的很爱你老婆就不要那么痴迷了,其实偶尔玩玩没关系,可是太痴迷的话会受不了的,反正我无法忍受男生太喜欢网络游戏。
我的签名档
ddddddddddddddddddddddddddddddddddddddddd
我现在都不玩CF 了 卡和***的那么多,起哦改玩***A了,虽然还在内测,不过很真实, 好像现在也有挂了55555555555
我的签名档
爆一切女楼主菊花!
叫你男友来和哥打CF,哥羞辱羞辱他,他就不打了
我是个女生也喜欢打CF.那游戏还可以哇.我男朋友是打WOW的,还团长,所以特别痴迷.但是只要我不输服不高兴,或者要他陪我,他就不会打了.挺安慰的.
楼主,你的鼻涕掉碗里了……
21楼的朋友,是不是男生找到对手就不会再打了???他一直都处于高手状态,几乎没人能打过他,你在哪个?让他找你打,打的落花流水就不会再喜欢了吧
我的签名档
。。。。。飘过
哥是江苏一区的 君临城下 来找我
好的好的,谢谢楼上
我的签名档
本人最重要
分了呗,让他继续跟电脑谈恋爱。
偶宿舍有个姐妹的男友也这样,看了就让人心寒。
是的,的确很让人心寒
CF RUBISH~
我的签名档
CF很垃圾的游戏 ,外G满天飞 ,楼主的男友竟然能沉迷于这样的游戏,我彻底无语了
我的签名档
CF很垃圾的游戏 ,外G满天飞 ,楼主的男友竟然能沉迷于这样的游戏,我彻底无语了
我的签名档
我也玩CF
33楼的,我也很无语
我的签名档
一起打散
这个帖子沉没了
我的签名档
不过我已经解脱了,谢谢楼上的所有朋友们
我的签名档
爱玩是太还小,不放手是因为在乎你
不是游戏比你重要,而是他有一颗贪玩的心
你不让他玩游戏了,他出去找女人你就高兴了?
39楼,是这样的么?
我的签名档
你觉得呢楼主
沉迷游戏当然不对
可也不是大错对么?和他好好谈谈吧
让他知道你非常不满意,在这么玩下去没将来的
为你为你们,应该好好努力。你说呢?
楼上的好厉害
42楼的朋友,他明明知道我讨厌他玩游戏,其实玩玩没什么,可是他特别痴迷,装备从来都是新的,他在战队是指挥官,是他们那组的组长,所以几乎每天都要去,这是很让人崩溃的事情,我无法说服他,可是和他分手他就会千方百计的找我,只要我不同意和他在一起,就会一直跟着我,简直让人发疯,我一直觉得最好的办法就是去一个他找不到的地方,可是目前我实在没有这个能力,我还没毕业,不能把时间都耗在这方面,我不知道要怎样摆脱这种状况
我的签名档
感情这种东西很纠结
,你一旦心里上有阴影之后,你会对他玩游戏这件事情很在意的
,最后就是你更不舒服
我的签名档
游戏打不出老婆和房子啊。 这道理都明白。但 就是喜欢玩也没办法
你男友愚蠢。CF能火几年?我也玩了一年半的CF后来因为种种原因不玩了,开始觉得挺可惜的,后来一想,cf是个什么啊?我至于吗?
猫扑网—中国第一互动娱乐门户 京ICP证041489号
千橡互动 Copyright 1997-2008 All Right Reserved
猫扑贴贴
猫扑大杂烩微软.NET精简框架(NETCF)最常见问题
2010-08-28 10:50:01
来源:西部e网
浏览次数:
此FAQ的内容,一部分来自
(microsoft.public.dotnet.framework.compactframework)张贴和回答的问题。.net精简框架开发小组感谢每一位参与新闻组的人事,感谢他们对FAQ编写的积极参与和对FAQ的投稿。
要申请添加FAQ项目,请发邮件到
. 1. 开发
微软.net精简框架是.net框架为智能设备开发的平台,是实现微软的目标:“为用户提供精彩的体验--任何时间、任何地点、任何设备” 的关键部分。.net精简框架把托管代码的世界从web服务带到了智能设备上, 允许在个人数字助理(PDA)、移动***、机顶盒设备上的 安全的、可下载的应用。
Visual Studio .NET 2003 是在Pocket PC 2000、Pocket PC 2002和Windows CE.NET 4.1上开发.net精简框架所需要的, .net精简框架与Visual Studio .NET 2003一同发售.
其他Windows移动平台开发包可以在以下地方获得:
Windows Mobile 2003 Pocket PC SDK:
Windows Mobile 2003 Smartphone SDK:
这篇文章将介绍如何使用.net精简框架和Visual Studio .NET 2003下开发健壮的智能设备应用程序.
Visual Studio .NET 2003试用版可以在这里获得:
最新的.net精简框架和补丁集可以在这里获得:
.net精简框架可以在Pocket PC 2000, Pocket PC 2002, Windows Mobile 2003的Pocket PC 和 基于Windows CE.NET 4.1嵌入式系统的Pocket PC、智能手机 上运行。
.net精简框架将被集成到微软系统中并成为一部分,包括未来的Pocket PC设备,Pocket PC***版,智能手机,车载Windows CE系统,MSTV。 各种设备的发布时间待定。
.net精简框架将作为Windows CE .NET 4.1系统组件的一部分,因此允许OEM厂商使用PlatformBuilder把.net精简框架集成到新的Windows CE设备中。
下面这个连接将告诉你如何设置调试和排错。
.NET框架 和 .net精简框架 的关系:
在线查看.net精简框架类库关系工具:
.net精简框架 SP1 修正了许多漏洞,查看修正项目列表:
这篇文章将描述在Pocket PC和Windows CE.NET平台上开发基于.net 精简框架的应用程序的区别之处。
以下资源能教会您怎样建立.net精简框架应用程序:
.net精简框架 快速入门
.net精简框架白皮书 MSDN移动和嵌入式开发中心:
在Visual Studio .NET 2003, 右键点击文件并选择属性,把
的属性设置为
文件将不再被拷贝.如果文件修改过了,需要重新拷贝,把Build属性改为Content即可.
在Visual Studio .NET 2003菜单中,选择
Tools-Optio .
Device Tools
文件夹,并选择
Devices.
您应该看到一个显示设备列表的对话框.选择您想修改的设备,按Configuration按钮.
现在您应该看到一个包含多个TAB并可以修改设置的对话框,如设置内存和屏幕大小等.
微软.net精简框架完全集成在Visual Studio .NET 2003中,在Visual Studio .NET 2003下调试.net精简框架的应用和在Visual Studio .NET 2003下调试其他应用一样。在一个单独的设备上调试程序和在模拟器中调试程序需要注意不同的地方。查看下面文章可以获得更多调试.net精简框架的经验。
了解怎样使用Smart Device Exte io (SDE)编写只能设备的应用。这篇文章详细介绍了在.net精简框架上开发、调试、发布的完整过程,并描述了和在.net框架上开发的区别。
This article illustrates the cause of a sharing violation that prevents the deployment of your a lication from Visual Studio .NET 2003, and gives i tructio on how to work around it.
.net精简框架提供的运行环境叫做CLR,它使程序运行,并且是开发更加容易。以下文章将使您了解更多关于CLR:
每一台装了.net环境的机器都会有一个本机器范围内的缓冲,这就是GAC。GAC中存放的装配会被这台计算机上的一些应用程序共享 。这篇文章将告诉你更多关于GAC的信息:
自动内存管理是CLR提供的一项服务。CLR的垃圾回收器会管理应用程序内存的分派和回收,以下文章将为您解释:
请查看本文章的 部分。
.net精简框架和它的执行引擎是.net框架和CLR的子集。缺省的强名称策略,针对.net精简框架编译的程序同样可以在完整的.NET框架上运行,但会有一些重要的异常信息:
.net精简框架装配使用和.net框架不用的强名称签名,所以CLR可以区分它们。
在未来发布的.NET框架和CLR的绑定策略中将使用.NET框架装配代替兼容.NET精简框架参考。这样,在普通情况下,不需要重新连接就能重用组件。 例如:如果您的组件只引用了.net精简框架的 System 和 System.NET 类库,它则不需要重新连接就适合在.net精简框架和完整的.NET框架下运行。
如果你引用了.net精简框架特有的功能,如PocketPC特有的用户界面,程序将不能在完整的.net框架上运行。
如跨平台的中间组件的开发和发布,微软认为丰富的客户端应用应该利用智能设备特有的功能为用户带来更好的体验。这一味着好的图形用户界面基本上是客户端特有的。
尽管微软花费很大精力为不同设备和功能划分了不同的命名空间和装配以避免装配冲突,但在1.0的版本里还是会有不能处理的兼容性问题。在这种情况下,在. net框架上不经意地使用了设备专有的功能将会导致程序在运行时的异常,而不是载入时的异常。
XScale支持ARM v5指令集,同时也向下兼容ARM v4指令集。这里有三种情况:
ARMv4 - 只支持32位ARMv4指令
ARMv4T - 'T' 表示 Thumb. Thumb 是ARM16位指令模式
ARMv4I - 'I' 表示 Interworking. 允许32位和16位指令共存
对于其他ARM处理器:
StrongARM (SA1110) - 只支持ARMv4指令
ARM920T, etc - 支持所有三种情况
.net精简框架支持三种ARM代码
ARMv4 for PocketPC 2000 and Pocket PC 2002. 支持所有ARM设备,包括XScale。发布到设备的CAB文件名包含有"arm"字符。
ARMv4 for Windows CE.NET. 支持由PlatformBuilder使用ARMv4核心编译的Windows CE.NET设备。Pocket PC 2003支持这种代码。发布到设备的CAB文件名包含有"armv4"字符。
ARMv4T or ARMv4I for Windows CE.NET. 支持由PlatformBuilder使用ARMv4T 或 ARMv4I核心编译的Windows CE.NET设备。发布到设备的CAB文件名包含有"armv4T"字符。
Visual Studio .NET 的发布中没有包括Windows CE的远程注册表编辑器。要修改注册键值,可以采用以下方法:
Microsoft Embedded Visual Tools Remote Registry Editor
Microsoft Windows CE Platform Builder Remote Registry Editor
PHM Pocket PC Registry Editor (共享软件,很容易在网上找到)
Automatic deletion of .CAB files can be prevented by setting the property of the .CAB file(s) to Read Only.
Each version of the .NET Compact Framework is released with a different Win32 File Version number (this is a separate version number from the A embly Version, which should be the same acro all releases of the Version 1 .NET Compact Framework, including Service Packs).
In order to see what version is i talled, use File Explorer to navigate to the \Windows directory on the device, and click the file called CGACUTIL. You will get a me age box showing you the Win32 File Version of the .NET Compact Framework i talled on the device.
RTM = 1.0.2268.0
SP1 = 1.0.3111.0
SP2 Recall = 1.0.3226.0
SP2 Beta = 1.0.3227.0
SP2 Final = 1.0.3316.0
To determine the version programmatically you can use System.Environment.Version.ToString().
One a roach would be to create a file share on your development PC, and then co ect to that share via File Explorer in the emulator. You may then copy and paste the files from the share to the emulator's local file system. Another a roach would be to add the file(s) to a smart device project and set their Build Action(s) property to "Content". See the Visual Studio .NET online documentation for more information on "File Properties":
Step by step i tructio for adding a "Content" file to a smart device project:
Open or create a smart device project,
On the View menu, click Solution Explorer,
In Solution Explorer, right-click on your project, point to Add, and click Add Existing Item. Browse to and add the desired file to the project.
Right-click on the file that you added, in solution explorer, and click Properties,
Set the Build Action property to "Content", if it is not already set.
Symptom:
The Pocket PC 2002 SDK i taller hangs while "registering components."
An unregestered component causes the i tallation to hang while attempting to run the emulator.
Workaround:
From a co ole window prompt:
cd \WINNT\system32
regsvr32 atl.dll
You need to attach the debugger to the ASP.NET worker proce .
Refer to the following link for more information:
.NET Compact Framework storage size:
1.55MB (ROM) on Pocket PC 2000/2002
1.35MB (ROM) on Windows Mobile for Pocket PC 2003 or Windows CE .NET Devices
Ru ing RAM requirements:
.5 MB+ (depends on a lication)
Typical a lication sizes:
5 - 100 KB
You must ask the OEM to include it in the device's image. If you are the OEM and you are using Platform Builder 4.2, then including the OS Dependencies for the .NET item automatically causes imgdecmp.dll to be part of the emulator image - if that is not working then refer to cesysgen.bat. Another method is to set the environment variable "__SYSGEN_IMGDECMP=1" to explicitly force the DLL into the image.
One can i tall and remove A emblies directly to and from the GAC by programmatically launching cgacutil.
Remove a emblies from the GAC using the -u option
I tall a emblies to the GAC using the -i option
It is typically safest to remove the A embly before rei talling it.
Download the ActiveSync Remote Di lay from Windows Mobile Developer Power Toys:
See the entry titled
of this FAQ.
See the entry titled
of this FAQ.
Download Ho er from Windows Mobile Developer Power Toys:
Download JShell from Windows Mobile Developer Power Toys:
Download PPC Command Shell from Windows Mobile Developer Power Toys:
Download RAPI Debug from Windows Mobile Developer Power Toys:
Download RAPI Start from Windows Mobile Developer Power Toys:
This is by design. You must either change the names of the DLLs, or if the DLLs are strong named, place them in the GAC and use A embly.Load with a full strong name.
Download the Emulator ActiveSync Co ection Tool from Windows Mobile Developer Power Toys:
This allows ActiveSync to co ect to your Emulator se ion from Visual Studio .NET 2003. Create an ActiveSync se ion to the 4.2 emulator, this will allow Visual Studio 2003 to co ider it a real device (Choose PPC device as the deployment target).
While adding designer su ort in Visual Studio .NET 2003 for Smart Device custom controls, you may run into the following i ues:
Unable to a ociate an Icon to the Control for showing it in the toolbox at design time
The component, when added to the toolbox, becomes greyed out
Using a design project separate from the control project. Visual Studio .NET automatically prepends the project default name ace to the bitmap name. The "default name ace" defaults to the project name. This may be a problem because the design project has a slightly different name than the runtime project.
Not setting the correct ToolBoxItemFilterAttribute values
Resolutio Given the following example:
Runtime VS.NET Project: MyProject
Cla Name: MyProject.MyCla Design VS.NET Project Name: MyProject.Design
BitMap name in VS.NET Design Project: Foo.bmp
Bitmap name in design a embly: MyProject.Design.MyCla .bmp
-- This creates a problem because the bitmap needs the name: MyProject.MyCla .bmp
In the above example, setting the design project's default name ace to "MyProject" rather then "MyProject.Design" should fix the problem.
The easiest way to check the name of the bitmap within the a embly is to run ILDASM and open the Manifest. The embedded resources are listed at the end of the manifest.
If you create a custom component derived from the Component cla , your code must include the following statements so that your component a ears in the Toolbox:
ToolBoxItemFilterAttribute("NETCF",ToolBoxItemFilterType.Require)
ToolBoxItemFilterAttribute("System.CF.Windows.Forms", ToolBoxITemFilterType.Custom)
2. 图形 有很多种方法可以建立图形对象,看你怎么用:
在OnPaint中,使用object参数提供的PaintEventArgs参数:
protected override void OnPaint(PaintEventArgs e)
e.Graphics.DrawLine(...);
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
e.Graphics.DrawLine(...)
End Sub 'OnPaint
在程序的其他部分,利用控件的一个方法,可以用来建立任意控件的图形对象:
using System.Drawing;
Graphics g = this.CreateGraphics();
Imports System.Drawing
Dim g As Graphics = Me.CreateGraphics()
直接画到bitmap位图文件中:
using System.Drawing;
Bitmap bm = new Bitmap(10,10);
Graphics g = Graphics.FromImage(bm);
Imports System.Drawing
Dim bm As New Bitmap(10, 10)
Dim g As Graphics = Graphics.FromImage(bm)
以下编码方式有助提高使用Graphics的绘图速度:
只建立一个图形对象 (或只使用OnPaint中的 PaintEventArgs)。
把所有绘图工作先画到不显示的位图上,再一次性把位图显示出来。
只重画变化的部分图象。
尽可能在相同的区域上画相同大小的图象。
主要思路:最小化地重画图象。例如,当光标拖过图象时,不需要把整个图重新画一遍。只需要重画光标之前经过的地方。
这里有个例子,告诉你怎样把图片画到窗体的背景上:
画一个带有透明色的图象,需要设置ImageAttributes对象的透明色。目前.net精简框架支持单种颜色的透明色。虽然SetColorKey 功能可以设置颜色范围,但颜色的最大值和最小值必须相同,不然在运行时会出现ArgumentException的错误:
using System.Drawing.Imaging;
ImageAttributes attr = new ImageAttributes();
Imports System.Drawing.Imaging
Dim attr As New ImageAttributes()
以下代码描述了如何根据图象左上角的颜色设置透明色。
attr.SetColorKey(bmp.GetPixel(0,0), bmp.GetPixel(0,0));
attr.SetColorKey(bmp.GetPixel(0,0), bmp.GetPixel(0,0))
以下方法可以准确的设置颜色:
attr.SetColorKey(Color.FromArgb(255,0,255),Color.FromArgb(255,0,255));
attr.SetColorKey(Color.Fuchsia, Color.Fuchsia);
attr.SetColorKey(Color.FromArgb(255,0,255),Color.FromArgb(255,0,255))
attr.SetColorKey(Color.Fuchsia, Color.Fuchsia)
图象会被重载的Graphics.DrawImage方法重画,并且使用ImageAttributes对象作为一个参数parameter:
g.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height,GraphicsUnit.Pixel, attr);
g.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height,GraphicsUnit.Pixel, attr)
只有Form类才支持Control.CreateGraphics().
使用Graphics的MeasureString方法。以下代码说明如何在文字周围画一个方框:
using System.Drawing;
protected override void OnPaint(PaintEventArgs e)
string s = "Hello World"
Pen pen = new Pen(Color.Fuchsia);
Font font = new Font("Arial", 18, FontStyle.Regular);
Brush brush = new SolidBrush(Color.Black);
SizeF sSize = e.Graphics.MeasureString(s, font);
Rectangle r = new Rectangle(9, 199,(int)sSize.Width + 1, (int)sSize.Height + 1);
e.Graphics.DrawRectangle(pen, r);
e.Graphics.DrawString(s, font, brush, 10.0f, 200.0f);
base.OnPaint (e);
Imports System.Drawing
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Dim s As String = "Hello World"
Dim pen As New Pen(Color.Fuchsia)
Dim font As New Font("Arial", 18, FontStyle.Regular)
Dim brush = New SolidBrush(Color.Black)
Dim sSize As SizeF = e.Graphics.MeasureString(s, font)
Dim r As New Rectangle(9, 199, Fix(sSize.Width) + 1, Fix(sSize.Height) + 1)
e.Graphics.DrawRectangle(pen, r)
e.Graphics.DrawString(s, font, brush, 10F, 200F)
MyBase.OnPaint(e)
End Sub 'OnPaint
Setting the pen width is not available in the .NET Compact Framework. Some alternate solutio include:
Drawing filled rectangles with the Graphics.FillRectangle method
Drawing multiple lines next to each other
Writing a custom graphics routine with GAPI
While there is no inherent su ort for zooming or stretching a single image, these effects can be achieved quite easily by creating a new Bitmap object with an a ociated Graphics object and copying the desired portion of the original Bitmap into it. The following sample creates two bitma of the same size, where the second contai a zoomed center section of the first, provided the project has an embedded resource named MyImage.bmp. This same technique could be used to stretch images by modifying the source and destination rectangles such that they do not maintain their original a ect ratio.
using System.Drawing;
using System.Reflectio Bitmap m_bmpOriginal;
Bitmap m_bmpZoom;
private void Form1_Load(object sender, System.EventArgs e)
A embly asm = A embly.GetExecutingA embly();
m_bmpOriginal = new Bitmap(asm.GetManifestResourceStream(asm.GetName().Name
+ ".MyImage.bmp"));
// Take the center quarter of m_bmpOriginal
// and create stetch it into m_bmpZoom of the same size
m_bmpZoom = new Bitmap(m_bmpOriginal.Width, m_bmpOriginal.Height);
Graphics gZoom = Graphics.FromImage(m_bmpZoom);
Rectangle srcRect = new Rectangle(m_bmpOriginal.Width / 4, m_bmpOriginal.Height / 4,
m_bmpOriginal.Width / 2, m_bmpOriginal.Height / 2);
Rectangle dstRect = new Rectangle(0, 0, m_bmpZoom.Width, m_bmpZoom.Height);
gZoom.DrawImage(m_bmpOriginal, dstRect, srcRect, GraphicsUnit.Pixel);
protected override void OnPaint(PaintEventArgs e)
e.Graphics.DrawImage(m_bmpOriginal, 0, 0);
e.Graphics.DrawImage(m_bmpZoom, 125, 0);
base.OnPaint (e);
Imports System.Drawing
Imports System.Reflection
Private m_bmpOriginal As Bitmap
Private m_bmpZoom As Bitmap
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim asm As [A embly] = [A embly].GetExecutingA embly()
m_bmpOriginal = New Bitmap(asm.GetManifestResourceStream((asm.GetName().Name _
+ ".MyImage.bmp")))
' Take the center quarter of m_bmpOriginal
' and create stetch it into m_bmpZoom of the same size
m_bmpZoom = New Bitmap(m_bmpOriginal.Width, m_bmpOriginal.Height)
Dim gZoom As Graphics = Graphics.FromImage(m_bmpZoom)
Dim srcRect As New Rectangle(m_bmpOriginal.Width / 4, m_bmpOriginal.Height / 4, _
m_bmpOriginal.Width / 2, m_bmpOriginal.Height / 2)
Dim dstRect As New Rectangle(0, 0, m_bmpZoom.Width, m_bmpZoom.Height)
gZoom.DrawImage(m_bmpOriginal, dstRect, srcRect, GraphicsUnit.Pixel)
End Sub 'Form1_Load
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
e.Graphics.DrawImage(m_bmpOriginal, 0, 0)
e.Graphics.DrawImage(m_bmpZoom, 125, 0)
MyBase.OnPaint(e)
End Sub 'OnPaint
E ure that imgdecmp.dll is in the device's Windows directory.
For more information, see the topic "
" of this FAQ.
3. 发布
这篇文章告诉您如何建立一个单独的.msi文件,可以运行并把应用***到不同的Pocket PC设备上。整个过程都是自动的,所以很容易把所有需要的组件都打包到.msi文件中。包含C#和Microsoft Visual Basic .NET代码。
您可以为您的用户提供一个最终的发布包,以帮助他们升级设备。您不能拆开这个发布包把内容给您的用户。但是,您可以拆开开发人员的发布包把内容给您的用户。
这篇文章讨论了如何成功的***一个Pocket PC的应用:
您可以建立一个.inf文件生成一个适合任何Pocket PC设备的应用程序***文件。查看示例代码:
每一个CAB文件都包含一小段检测智能设备上的.net精简框架版本的代码。这个功能是处理器/平台特有的,不同的CAB文件根据处理器类型绑定不同的代码。
The article titled "Creating an MSI Package that Detects and Updates the .NET Compact Framework" in the MSDN Library describes a technique that may be used:
Download and i tall to your desktop development PC a "Developer" version of the service pack (the download title will read something like: "Microsoft?? .NET Compact Framework 1.0 SPx
Developer
Redistributable") from:
The next step is to copy the a ropriate .NET Compact Framework cab file (as per next paragraph) to the emulator. From within the emulator point File Explorer to a share on your PC and then copy and paste the cab to somewhere on the emulator's file system. Now launch the cab file from File Explorer and a wer "Yes" if asked to overwrite anything. Emulator
CAB File
Pocket PC 2002
netcf.core. c3.x86.cab
Windows Mobile 2003 for Pocket PC
netcf.core.wce4.x86.cab
Windows Mobile 2003 for Smartphone
RAM i talls not su orted
To i tall SQL Server CE with an a lication, simply i tall the proper SQL Server CE CAB files as part of the a lication's i tallation. There are two sets of ca a ociated with SQL Server CE.
The developer CAB includes Query Analyzer, and error strings. This CAB should not be included with a lication deployment. It comes in two actual files, one for Pocket PC and one for Windows CE 4.x devices:
sqlce.dev. c3.< roce or.cab
sqlce.dev.wce4.< roce or.cab
The SQL Server CE CAB, which includes the engine, client agent, and managed exte io for the client agent is required by a licatio utilizing System.Data.SqlServerCe components. This CAB also comes in two actual files, one for Pocket PC and one for Windows CE 4.x devices:
sqlce. c3.< roce or.cab
sqlce.wce4.< roce or.cab
A licatio that acce SQL Server, ie a licatio utilizing System.Data.SqlClient components should deploy the 'sql' CAB. This CAB also comes in two actual files, one for Pocket PC and one for Windows CE 4.x devices:
sql. c3.< roce or.cab
sql.wce4.< roce or.cab
All of these CABs are included in the Visual Studio .NET 2003 Profe ional Edtion i tall. The default location is:
\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\...
This article describes how to create a DLL that wra GAPI (Game API), such that it is .NET Compact Framework compliant, and use it to create and optimize a basic graphics library in managed code.
This article expands upon the "Dancing Rectangles" sample by implementing loading and di laying of bitma . It also implements some more advanced features such as animated bitma , source and destination key tra arency, and alpha blending, i.e., tra lucency.
This article expands upon the "Dancing Zombies" sample by implementing drawing of points, lines, and custom 1 bit fonts converted from 8 bit bitma . It also implements an i ut system that overrides the functionality of the hardware butto and tracks button states. 4. 图形用户界面(GUI): 窗体
您必须把WindowState属性设置为最大化。做一个看不见的窗体,如把全屏的图片放到窗体中,您需要把FormBorderStyle设置为None,关掉ControlBox删掉窗体中所有的菜单。
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
this.ControlBox = false;
this.Menu = null;
Me.WindowState = FormWindowState.Maximized
Me.FormBorderStyle = FormBorderStyle.None
Me.ControlBox = False
Me.Menu = Nothing
窗体的load功能是做界面操作的最好方法。典型又安全的做法是在构造器中创建数据和控件的实例。任何包含用户界面的控件或窗体的初始化,都应该在 load功能中完成。例如:在窗体的构造器中完成控件对象的建立,然后在load功能中设置控件的位置等 是安全的做法。
通过开发环境的设计器,可以把窗体的自动最小化模式转变成关闭模式,或者通过变成实现。(x)按钮自动最小化应用程序,(ok)按钮回关闭程序。
在设计器中转化窗体的风格
打开Visual Studio环境的窗体设计器,查看属性。在窗体上右键并选择
Properties,
Window Style
部分把MinimizeBox设置为
False。
在代码中转变窗体风格
简单的在窗体的load功能中添加以下一行代码:
this.MinimizeBox = false;
Me.MinimizeBox = False
这篇文章讨论了如何在.net精简框架上为应用程序有效的建立用户界面:
通过下面文章中的优化技巧,减少.net精简框架应用程序的载如时间:
这篇快速入门教程描述了在pocket pc应用程序中使用代码改变窗体界面:
这篇快速入门教程演示了如何使用纵向和横向滚动条 还有如何在窗体中绘制一个图象:
有边界的最顶端的窗体总是全屏的,不能移动或改变大小。没有边界或子窗体可以移动和改变大小。
使用: Form.BorderStyle = BorderStyle.None //来设置有无边界
请查看本问 "
" 部分。
如果你的窗体中包含了很多控件,当你运行的时候可能会有NotSu ortedException的错误。如果你是在Debug模式下运行的话,你会发现异常是来自于窗体的InitializeComponent部分。这种情况是由于精简框架CLR在编译类的方法时,会有64kb的限制造成的。这意味着 CLR把方法(如,InitializeComponent)翻译成中间语言时,返回的机器码不能超过64KB。如果超过了64KB, NotSu ortedException将被抛出。这也是为什么容易在Debug模式(F5)下导致错误,而非Debug模式(Ctrl+F5)却不容易出错。因为Debug模式运行时会生成更多容量的调试代码。
除了模拟器,您也可能在智能设备上遇到这个错误,因为即时编译代码根据因CPU类型而异的(如,PocketPC使用的是ARM指令,而模拟器上使用的x86指令)
没有一个准确的数字说明,一个窗体中到底可以包含多少个控件。因为不同控件的产生的代码量不一样。如,一个Button控件,比TabControl控件产生的代码要少。还会因由设置了多少属性而异。包含集合的控件,象ListBox或TreeView,如果在设计时向属性框中填入了很多值,编译时将产生大量代码。同样,设置了Localized的窗体(Localizable属性为true),会比没设置localize的窗体产生更多代码。因为 localize需要从资源文件中读取属性值,放在InitializeComponent方法中。
果你遇到这种情况,下面有一些技巧帮助你避免它的发生:
把一个窗体的代码分成多个窗体。过多控件的窗体,会影响程序开始时载入的性能。尽可能把用户界面分成两个或多个窗体。
不要在设计时填充大的、内部的、带集合的控件。如果你把很多节点集合加到TreeView控件中,这样会在InitializeComponent方法中加入大量代码。尽可能把加入集合的代码移到Form.Load事件中。这样做的缺点是,要在设计时编辑这些集合将变得不容易,但它有助于分割代码。
不要把自己的代码添加到InitializeComponent方法中,这对通常的编码都有用,不建议添加、修改设计起生成的代码。这样做会造成设计器不可知的错误。如果你想添加自己的启动代码,你应该在Form.Load事件中做。
运行时初始化类似的控件。比如,有12个Button控件,只是文字和位置不同,你应该考虑使用循环来设置属性,而不是在设计时设置属性。在次,如果你自己写代码来实现它,不要把代码放在InitializeComponent方法中。
编辑InitializeComponent方法的缺点是,在InitializeComponent代码外建立对象实例的代码,将不能在设计器重被设计。同样,如果你手动修改了InitializeComponent中的代码,你会发现,设计器可能不再识别你修改的代码。所以以上技巧的前提是,不要修改InitializeComponent中的代码。
A lication.Exit是类似Win32平台下的PostQuitMe age()硬性退出。收回所有弹出的信息,释放呼叫堆栈,把执行权返回给系统。
在windows平台(Win32或.NET)下正确关闭应用程序的方法是关闭主窗体(如:Form.Close)。所有主窗体结束时仍存在的窗体需要手工关闭。Any window that's still present after the main me age pump ends needs to be manually closed. 好的方法就是在应用程序调用Form.Close或Form.Di ose退出之前,关闭所有窗体。需要记住.NET框架的OnClosing()就是Win32平台下WM_CLOSE的托管版本,而不是WM_DESTROY。
另外,使用form.Close()的话,你的程序可以在OnClosing或OnClosed事件中处理释放资源、关闭文件等操作。如果使用A lication.Exit退出,这些事件将不会被触发。
Windows Mobile 2003 for Smartphone only su orts 1 or 2 button Me ageBoxes.
Create a shortcut to your a lication somewhere under \windows\start menu\programs. When your a lication is launched from this shortcut an icon for your a licatio will a ear the MRU list.
In order to di lay a non-full screen Form, e ure that the Form's FormBorderStyle property is set to FormBorderStyle.None. To center the form add the following code to the Form's FormLoad event handler: Set FormBorderStyle to FormBorderStyle.None then:
Rectangle screen = Screen.PrimaryScreen.Bound this.Location = new Point((screen.Width - this.Width) / 2,
(screen.Height - this.Height ) / 2);
Dim theScreen As Rectangle
theScreen = Screen.PrimaryScreen.Bounds()
Me.Location = New Point((theScreen.Width - Me.Width) / 2, _
(theScreen.Height - Me.Height) / 2)
Once a Form is closed, it is di osed and therefore may be garbage collected by the system so it is not safe to attempt to show a closed Form. An alternative solution is to use Form.Hide and Form.Show to hide and di lay Forms re ectively.
Multi-i tancing is not su orted by the .NET Compact Framework. The following code sample provides a solution that allows a licatio to be i tanced rather than maximized when an a lication is launched but a ru ing i tance already exists.
The following code is not su orted and is not guaranteed to work on all versio of the OS, including future versio .
using System.Runtime.InteropService using System.Reflectio private void Form1_Load(object sender, System.EventArgs e)
this.Text = string.Format("Form {0}", new Random().Next());
[DllImport("CoreDll")]
public static extern IntPtr FindWindow(string lpCla Name, string lpWindowName);
[DllImport("CoreDll")]
public static extern int SetWindowText(IntPtr hWnd, string lpString);
protected override void OnResize(EventArgs e)
A embly asm = System.Reflection.A embly.GetExecutingA embly();
IntPtr hWnd = FindWindow("#NETCF_AGL_PARK_",
asm.GetModules()[0].FullyQualifiedName);
if (hWnd != IntPtr.Zero)
SetWindowText(hWnd, "#42");
base.OnResize (e);
Imports System.Runtime.InteropServices
Imports System.Reflection
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Me.Text = String.Format("Form {0}", New Random().Next())
End Sub 'Form1_Load
DllImport("CoreDll") _
Public Shared Function FindWindow(ByVal lpCla Name As String, _
ByVal lpWindowName As String) As IntPtr
End Function
DllImport("CoreDll") _
Public Shared Function SetWindowText(ByVal hWnd As IntPtr, _
ByVal lpString As String) As Integer
End Function
Protected Overrides Sub OnResize(ByVal e As EventArgs)
Dim asm As [A embly] = System.Reflection.A embly.GetExecutingA embly()
Dim hWnd As IntPtr = FindWindow("#NETCF_AGL_PARK_", _
asm.GetModules()(0).FullyQualifiedName)
If hWnd.ToInt32() IntPtr.Zero.ToInt32() Then
SetWindowText(hWnd, "#42")
MyBase.OnResize(e)
End Sub 'OnResize 5. 图形用户界面 (GUI): 通用
建立一个带有图形或支持多行的按钮需要使用自定义控件。自定义控件能继承button的paint方法,以及其他任何需要的自定义数据。参考以下连接获得更多关于自定义控件的信息:
快速入门教程告诉你如何建立一个带图像的按钮:
虽然设置了AcceptsReturn为false,但它还是按true的方式来操作。你可以写一个继承TextBox的类,在KeyPre 事件中实现对Enter的处理。
这是一个已经知道的问题,将在以后的.net精简框架中发布。
ShowDialog会把一个窗体以 模式 方式显示,这是一种独占调用方式,知道窗体关闭才会返回。这个方法将返回一个DialogResult枚举,表示关闭的条件。
Show是一种非独占的调用方式,和显示一个控件一样,可以立刻返回,没有返回参数。显示一个控件意味着Visible属性被设置为true,直到Hide方法被调用,Visible方法才会变为false。
这是一个已经知道的BUG,把右键菜单设置为分割线,将抛出NotSu ortedException错误。这个问题是由于WinCE系统有个限制,不允许在已经加入右键菜单的菜单项设置为分隔符,并且菜单的父类是一个控件。在Visual Studio 2003种,设计器分割移动应用代码的方式和PC上的应用程序类似。这是导致此问题的原因。解决的方法是,把右键菜单单独放在InitilizeComponent方法外的地方。
你可以在窗体载入的时候把ImageList分配给ToolBar,但重新应用图像在ToolBar上的顺序。在设置ToolBar的ImageList之前 设置ToolBar按钮的图像顺序是不被支持的。
这段代码可以把光标设置成等待光标:
Cursor.Current = Cursors.WaitCursor;
Cursor.Current = Cursors.WaitCursor
这段代码可以把光标设置为默认:
Cursor.Current = Cursors.Default;
Cursor.Current = Cursors.Default
这项功能还不被.net精简框架支持。使用"&am am "不会在菜单项的文字中显示"&am "符号。
这篇文章将告诉你如何制作基于.net精简框架的动画控件:
学习制作.net精简框架控件,提高您的技巧。(文章附带了自定义控件的示例代码):
这篇文章讨论了建立基于.net精简框架的带图片的按钮:
学习如何使用.net精简框架 Me ageWindow 类建立一个提示图标:
这篇快速入门实现了,当鼠标点击矩形自定义控件或点击Panel控件时,使用Me ageWindow把消息发送给发送窗体:
这篇快速入门教程解释了如何在运行时向DataGrid控件添加或删除行、列:
.net精简框架中的DataGrid控件提供了几乎.net框架中的DataGrid控件的所有功能。一个主要的区别是.net精简框架中的DataGrid不能在运行时编辑单元。这篇快速入门教程演示了如何通过程序实现编辑单元格的一种方法:
与.net框架的DataGrid的另一个区别是,.net精简框架的DataGrid不支持把DataSource设置为DataSet。
与.net框架的DataGrid的另一个区别是,.net精简框架的DataGrid不支持在运行时按照列进行排序。
.net精简框架不支持ListView.Sort方法,但任然可以排序。这篇快速入门教程定义了一个继承ArrayList.Sort的IComparable接口的方法:
这篇快速入门教程演示了在PocketPC上打开和关闭软输入板(SIP),以及当SIP显示时,tab控件大小也跟随变化:
多个窗体应该共享一个输入板对象。可以通过先在主窗体中建立SIP对象,然后把它传给子窗体或暴露SIP对象的一些方法、属性给其他需要使用SIP的窗体。
这篇快速入门教程描述了如何继承Button类、重载方法来事现双击事件。这个自定义事件会在按钮被双击时触发,两次点击的间隔时间是SystemInformation.DoubleClickTime 属性的值,以毫秒为单位。
.net精简框架的控件不支持OnEnter和OnLeave方法,包括Windows.Forms.Control基类。但是,因为支持Control.OnMouseMove方法,您可以通过它和Control.Capture 属性判断鼠标什么时候进入和离开控件。
您可以制作一个.net精简框架的owner drawn list box。.net精简框架的ListBox或其他控件不支持DrawMode、DrawItem, 或其他drawing方法,但您可以编程实现。这篇快速入门教程提供一个自定义控件类,建立一个owner-drawn list box,并实现了选择字体的控件的功能。
这篇快速入门教程提供了在Windows.Forms.CheckBox控件上建立真/假多选框:
I utPanel组件需要窗体包含MainMenu控件,而且那个窗体是显示在屏幕上的。
这个功能不被.net精简框架所支持。
在代码中改变控件的值 或 按下了上、下箭头才会触发ValueChanged和SelectedItemChanged事件。当用户往控件中输入字符的时候时不会触发的。
当您按了上、下后出现的值,不是增长值的倍数,它将向着那个方向(上或下)直到下一个增长值的倍数的值。
StatusBar控件只能停靠在窗体的底部,它的大小不能改变。
这个功能不被.net精简框架所支持。可以采取的方法是继承OnParentChanged方法手动设置颜色:
protected override void OnParentChanged(EventArgs e)
base.OnParentChanged(e);
this.BackColor = Parent.BackColor;
Protected Overrides Sub OnParentChanged(ByVal e As EventArgs)
MyBase.OnParentChanged(e)
Me.BackColor = Parent.BackColor
End Sub 'OnParentChanged
虽然NumericUpDown控件接受decimal类型的值,但.net精简框架把这个控件的值当作int类型来处理。如,10.23当作10。同样此控件在PocketPC上不接受大于带符号的16位整型。
DomainUpDown控件不会对输入的文字进行确认(不象完整的.net框架)。如果您先输入了一些文字,再按上、下箭头,它会显示内容改变前的值的下一个值。
OpenFileDialog的初始化目录被限制在"My Documents"文件夹或它的子文件夹中。这个限制是由PocketPC系统强加的,为了帮助用户在标准目录下管理自己的文档。 The SIP can be activated by P/Invoking the function "SipShowIM" as follows.
using System.Runtime.InteropService co t uint SIPF_OFF = 0x0;
co t uint SIPF_ON = 0x1;
[DllImport("coredll.dll")]
private extern static void SipShowIM(uint dwFlag);
Imports System.Runtime.InteropServices
Co t SIPF_OFF As Integer = &am H0
Co t SIPF_ON As Integer = &am H1
DllImport("coredll.dll") _
Private Shared Function SipShowIM(ByVal dwFlag As Integer) As Integer
End Function
Adding su odes to all nodes is accomplished by iterating through all of the nodes in the TreeView and adding a new node to each.
foreach (TreeNode node in treeView1.Nodes)
{ node.Nodes.Add(new TreeNode("SubNode"));
Dim node As TreeNode
For Each node I treeView1.Nodes node.Nodes.Add(New TreeNode("SubNode"))
Next node
The number of rows and colum in a DataGrid can be determined from the data source itself. For example:
DataSet ds = new DataSet();
int numRows = ds.Tables[0].Rows.Count;
int numCols = ds.Tables[0].Colum .Count;
Dim ds As New DataSet()
Dim numRows As Integer = ds.Tables(0).Rows.Count
Dim numCols As Integer = ds.Tables(0).Colum .Count
If the DataGrid is bound to the DataView you can also use DataView.Count.
See the .NET Compact Framework QuickStarts, Implementing Events topic:
The tab order of the controls in the .NET Compact Framework corre ond directly to the order of the Controls in the Form.Controls collection. Therefore, GetNextControl can be implemented by determining the index of the ecified Control and determing its neighbors in the collection.
public Control GetNextControl(Control ctl, bool forward)
int curIndex = this.Controls.IndexOf(ctl);
if (forward)
if (curIndex this.Controls.Count)
curIndex++;
curIndex = 0;
if (curIndex 0)
curIndex--;
curIndex = this.Controls.Count - 1;
return this.Controls[curIndex];
Public Function GetNextControl(ByVal ctl As Control, _
ByVal forward As Boolean) As Control
Dim curIndex As Integer = Me.Controls.IndexOf(ctl)
If forward Then
If curIndex Me.Controls.Count Then
curIndex += 1
curIndex = 0
If curIndex 0 Then
curIndex -= 1
curIndex = Me.Controls.Count - 1
Return Me.Controls(curIndex)
End Function 'GetNextControl
TreeView does not su ort the Click event, however, a workaround is to use the AfterSelect event i tead.
This is not su orted by the current version of the .NET Compact Framework.
Setting the SelectedValue property only works if the control is databound.
Handle the ContextMenu.Popup event, and then query the current mouse coordinates using 'Control.MousePosition'.
Similar to the NumericUpDown control, the maximum achievable value is the first empty row above the thumb. More ecifically, from the editor properties, this equates to:
Maximum - (LargeChange + 1).
Call this.Parent.Controls(this.Parent.GetChildIndex(customcontrol) - 1).Focus() in the KeyDown event handler when a Keys.Up key is detected.
Ico su ort tra arency, however, there is a known bug in Visual Studio .NET 2003 designer that creates incorrect code and makes ico non-tra arent. A work around is to add an icon file to the ImageList outside of InitializeComponent and add the icon files to the project as content or embedded resources. The following code demo trates this:
using System.Drawing;
using System.IO;
using System.Reflectio // Loaded as content example
private void Form1_Load(object sender, System.EventArgs e)
this.imageList1.Images.Add(new Icon(File.Open("fullFileName.ico",
FileMode.Open)));
this.toolBar1.Butto [0].ImageIndex = 0;
// Loaded as a resource example
private void Form1_Load(object sender, System.EventArgs e)
this.imageList1.Images.Add(new
Icon(A embly.GetExecutingA embly().GetManifestResourceStream(
".filename.ico")));
this.toolBar1.Butto [0].ImageIndex = 0;
Imports System.Drawing
Imports System.IO
Imports System.Reflection
' Loaded as content example
Private Sub Form1_Load1(ByVal sender As Object, ByVal e As System.EventArgs)
Me.imageList1.Images.Add(New Icon(File.Open("fullFileName.ico", _
FileMode.Open)))
Me.toolBar1.Butto (0).ImageIndex = 0
End Sub 'Form1_Load1
' Loaded as a resource example
Private Sub Form1_Load2(ByVal sender As Object, ByVal e As System.EventArgs)
Me.imageList1.Images.Add(New _
Icon([A embly].GetExecutingA embly().GetManifestResourceStream( _
".filename.ico")))
Me.toolBar1.Butto (0).ImageIndex = 0
End Sub 'Form1_Load2 6. 与本地代码(Native Code)互用
本地DLL代码可以通过系统的Invoke (P/Invoke)方法调用。这些文章提供了如何实现调用和更多的调用技巧:
学习如何使用.net精简框架的Platform Invoke (P/Invoke)细节:
深入探索.net精简框架下的互用性。
学习如何通过P/Invoke建立智能设备上的非托管代码。
如何在.net精简框架上汇集托管和非托管代码的数据。
学习使用工具dum in.exe在微软.net精简框架的应用中申明P/Invokes。
见本问答的 "
" 章节。
见本问答的 "
" 章节。
不需要使用P/Invoke调用GetTickCount功能,因为Environment.TickCount就提供了这个功能。
见本问答的 "
您可以调用GetSystemMemoryDivision和GlobalMemorySystem函,数获得程序和存储器间有多少内存是隔离的和已经分配的。
参数的说明可以在API参考文档中找到。
using System.Runtime.InteropService public cla MEMORYSTATUS
public uint dwLength;
public uint dwMemoryLoad;
public uint dwTotalPhy public uint dwAvailPhy public uint dwTotalPageFile;
public uint dwAvailPageFile;
public uint dwTotalVirtual;
public uint dwAvailVirtual;
[DllImport("CoreDll.dll")]
public static extern void GlobalMemoryStatus
MEMORYSTATUS lpBuffer
[DllImport("CoreDll.dll")]
public static extern int GetSystemMemoryDivision
ref uint lpdwStorePages,
ref uint lpdwRamPages,
ref uint lpdwPageSize
public void Test()
uint storePages = 0;
uint ramPages = 0;
uint pageSize = 0;
int res = GetSystemMemoryDivision(ref storePages, ref ramPages, ref pageSize);
MEMORYSTATUS memStatus = new MEMORYSTATUS();
GlobalMemoryStatus(memStatus);
Imports System.Runtime.InteropServices
Public Structure MEMORYSTATUS
Public dwLength As UInt32
Public dwMemoryLoad As UInt32
Public dwTotalPhys As UInt32
Public dwAvailPhys As UInt32
Public dwTotalPageFile As UInt32
Public dwAvailPageFile As UInt32
Public dwTotalVirtual As UInt32
Public dwAvailVirtual As UInt32
End Structure 'MEMORYSTATUS
DllImport("coredll.dll") _
Private Shared Sub GlobalMemoryStatus(ByRef ms As MEMORYSTATUS)
End Sub
DllImport("CoreDll.dll") _
Public Shared Function GetSystemMemoryDivision( _
ByRef lpdwStorePages As UInt32, _
ByRef lpdwRamPages As UInt32, _
ByRef lpdwPageSize As UInt32) As Integer
End Function
Public Shared Sub Test()
Dim storePages As UInt32
Dim ramPages As UInt32
Dim pageSize As UInt32
Dim res As Integer = GetSystemMemoryDivision(storePages, ramPages, pageSize)
Dim memStatus As New MEMORYSTATUS
GlobalMemoryStatus(memStatus)
End Sub 'Test
继承窗体的OnGotFocus方法。
找到窗体的窗口句柄。
调用ShowWindow(hwnd, SW_MINIMIZE)强制窗体最小化。
using System.Runtime.InteropService [DllImport("CoreDll")]
public static extern IntPtr FindWindow(string cla Name,string WindowsName);
[DllImport("CoreDll")]
public static extern bool ShowWindow(IntPtr hwnd,int nCmdShow);
co t int SW_MINIMIZE = 6;
protected override void OnGotFocus(EventArgs e)
IntPtr hwnd = FindWindow(null, this.Text);
ShowWindow(hwnd, SW_MINIMIZE);
base.OnGotFocus(e);
Imports System.Runtime.InteropServices
DllImport("CoreDll") _
Public Shared Function FindWindow(ByVal cla Name As String, ByVal WindowsName As String) As IntPtr
End Function
DllImport("CoreDll") _
Public Shared Function ShowWindow(ByVal hwnd As IntPtr,ByVal nCmdShow As Integer) As Boolean
End Function
Private Co t SW_MINIMIZE As Integer = 6
Protected Overrides Sub OnGotFocus(ByVal e As EventArgs)
Dim hwnd As IntPtr = FindWindow(Nothing, Me.Text)
ShowWindow(hwnd, SW_MINIMIZE)
MyBase.OnGotFocus(e)
End Sub 'OnGotFocus
见本问答的 "
" 章节。
其实有一些使用调用本地代码的方法可以获得控件的句柄HWND。下面列出其中两种,一种使用GetCapture,另一个使用FindWindow。
[DllImport("coredll.dll"]
public static extern IntPtr GetCapture();
[DllImport("coredll.dll")]
public static extern IntPtr FindWindow(String lpCla Name, String lpWindowName);
this.Text = "FindMe";
IntPtr hwnd1 = FindWindow(null, "FindMe");
this.Capture = true;
IntPtr hwnd2 = GetCapture();
this.Capture = false;
DllImport("coredll.dll", SetLastError:=True) _
Public Shared Function GetCapture() As IntPtr
End Function
DllImport("coredll.dll", SetLastError:=True) _
Public Shared Function FindWindow(ByVal lpCla Name As String, ByVal lpWindowName As String) As IntPtr
End Function
Me.Text = "FindMe"
Dim deskWin As IntPtr = FindWindow(Nothing, "FindMe")
Me.Capture = True
Dim hwnd As IntPtr = GetCapture()
Me.Capture = False
使用QueryPerformanceFrequency函数和QueryPerformanceCounter函数可以建立精确的计时程序。这些功能是和设备提供商相关的,如果他们不能执行,那么只能和GetTickCount功能得到一样的结果。如果能执行这些函数,就能保证计时器最准确的运行,比GetTickCounter或Environment.TickCount准确得多。TickCount其实是调用 GetTickCounter的。
如果性能计数器是GetTickCount的一个实例,QueryPerformanceFrequency将把1000作为计时频率。如果这些函数不能执行,将得到返回值为0。以下代码演示了如何使用这些函数。
[DllImport("CoreDll.dll")]
public static extern int QueryPerformanceFrequency(ref Int64 lpFrequency);
[DllImport("CoreDll.dll")]
public static extern int QueryPerformanceCounter(ref Int64 lpPerformanceCount);
private void TestTimer()
System.Int64 freq = 0;
if (QueryPerformanceFrequency(ref freq) != 0)
System.Int64 count1 = 0;
System.Int64 count2 = 0;
if (QueryPerformanceCounter(ref count1) != 0)
System.Threading.Thread.Sleep(1200);
QueryPerformanceCounter(ref count2);
System.Int64 time_ms = (count2 - count1) * 1000 / freq;
DllImport("CoreDll.dll") _
Public Shared Function QueryPerformanceFrequency(ByRef lpFrequency As Int64) As Integer
End Function
DllImport("coredll.dll") _
Public Shared Function QueryPerformanceCounter(ByRef lpPerformanceCount As Int64) As Integer
End Function
Private Sub TestTimer()
Dim freq As System.Int64 = 0
If QueryPerformanceFrequency(freq) 0 Then
Dim count1 As System.Int64 = 0
Dim count2 As System.Int64 = 0
If QueryPerformanceCounter(count1) 0 Then
System.Threading.Thread.Sleep(1200)
QueryPerformanceCounter(count2)
Dim time_ms As System.Int64 = (count2 - count1) * 1000 / freq
End Sub 'TestTimer
只能是长度小于等于32位的类型
非浮点型not floating point
Only su ort marshaling blittable types
blittable types - same representation in memory in both managed and native
non-blittable - memory tra formation required
Since only blittable types, all objects are pi ed and never copied
Exception: pa ing String ByVal in VB.NET
Implies that you can't marshal nested objects since this requires a memory tra formation (non-blittable)
只能是长度小于等于32位的类型
值通过堆栈传递
例外:float32
参考(References)
Pa blittable reference types
把参考传递到值类型变量
这就是如何传递float32类型的值
可以传递值类型的数组
在本地代码中,您可以使用指针指向第一个对象,然后一个接一个地访问其他对象
String是特殊的,传递char数组 - 不变的
StringBuilder是特殊的,传递char数组 - 易变的 (需要单独传递长度)
注意:C# bool是8个比特位的,并且不等于Win32的BOOL
队列:编译器默认的队列 (4字节)
Marshal.GetLastWin32Error 支持 GetLastError() 语义
未支持的:
MarshalAs: no su ort for non-blittable types
StructLayout: 不能改变外观
Delegates(委托)
DateTime
Only su ort default calling convention
尽量不要尝试调用Windows GetLastError() API,因为CLR调用本地代码时可能会改变last error的代码。取而代之的是,使用调用的返回值标记错误代码,再调用System.Runtime.InteropServices.Marshal.GetLastWin32Error()方法来获得错误代码。
using System.Runtime.InteropService [DllImport("coredll.dll", SetLastError=true)]
int myFoo(...);
Foo(...)
int rc = myFoo(...);
if (rc == false)
throw new Win32Exception(Marshal.GetLastWin32Error(), "Foo failed");
有限制。.net精简框架版本1.0的限制为12个。
通常有三种可能性:
在托管代码中的申明不正确
.net精简框架不支持你想做的操作
dll的名称在暴露过程中损坏了
检查以下项目: 有没有违反.net精简框架 P/Invoke(调用)的限制?
有没有参数需要预先分配内存(如,是不是指针)? 如果是的,您应该传递已经存在的变量的参考。
暴露的函数名是否正确? 可以用DUMPBIN.EXE工具来验证
是不是想尝试太多的参数?
例如,针对上面的第二点,RegOpenKey API的最后一个参数HKEY的指针。您应该这样申明和调用:
[DllImport("coredll.dll", SetLastError=true)]
public static extern long RegOpenKey(
IntPtr hkey,
string lpSubKey,
ref IntPtr hkeyResult
public long OpenMySubKey()
IntPtr hkey = IntPtr.Zero;
return RegOpenKey(HKEY_CLASSES_ROOT, "MySubKey", ref hkey);
DllImport("coredll.dll", SetLastError:=True) _
Public Shared Function RegOpenKey(ByVal hkey As IntPtr, ByVal lpSubKey As String, ByRef hkeyResult As IntPtr) As Long
End Function
Public Function OpenMySubKey() As Long
Dim hkey As IntPtr = IntPtr.Zero
Return RegOpenKey(HKEY_CLASSES_ROOT, "MySubKey", hkey)
End Function 'OpenMySubKey
有不止一种的方法访问IntPtr。
第一种方法,使用非安全代码,直接用指针指向byte数组。
byte[] test = new byte[5];
fixed (byte* p = &am test[0])
*p = 0xff;
也可以使用GCHandle指向对象。
using System.Runtime.InteropService byte[] test = new byte[5];
GCHandle hObject = GCHandle.Alloc(test, GCHandleType.Pi ed);
IntPtr pObject = hObject.AddrOfPi edObject();
if(hObject.IsAllocated)
hObject.Free();
Imports System.Runtime.InteropServices
Dim test(4) As Byte
Dim hObject As GCHandle = GCHandle.Alloc(test, GCHandleType.Pi ed)
Dim pObject As IntPtr = hObject.AddrOfPi edObject()
If hObject.IsAllocated Then
hObject.Free()
最后,可以使用LocalAlloc和Marshalling函数复制内存块得到数据块。
[DllImport("coredll.dll",SetLastError=true)]
public static extern IntPtr LocalAlloc(uint uFlags, uint uBytes);
[DllImport("coredll.dll",SetLastError=true)]
public static extern IntPtr LocalFree(IntPtr hMem);
[DllImport("coredll.dll",SetLastError=true)]
public static extern IntPtr LocalReAlloc(IntPtr hMem, uint uBytes, uint fuFlags);
public co t uint LMEM_FIXED = 0;
public co t uint LMEM_MOVEABLE = 2;
public co t uint LMEM_ZEROINIT = 0x0040;
byte[] test = new byte[5];
IntPtr p = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (uint)test.Length);
if (p == IntPtr.Zero)
throw new OutOfMemoryException();
Marshal.Copy(test, 0, p, test.Length);
DllImport("coredll.dll", SetLastError:=True) _
Public Shared Function LocalAlloc(ByVal uFlags As UInt32, ByVal uBytes As UInt32) As IntPtr
End Function
DllImport("coredll.dll", SetLastError:=True) _
Public Shared Function LocalFree(ByVal hMem As IntPtr) As IntPtr
End Function
DllImport("coredll.dll", SetLastError:=True) _
Public Shared Function LocalReAlloc(ByVal hMem As IntPtr, ByVal uBytes As UInt32, ByVal fuFlags As UInt32) As IntPtr
End Function
Public Co t LMEM_FIXED As Integer = 0
Public Co t LMEM_MOVEABLE As Integer = 2
Public Co t LMEM_ZEROINIT As Integer = &am H40
Dim test(4) As Byte
Dim p As IntPtr = LocalAlloc(Convert.ToUInt32(LMEM_FIXED Or LMEM_ZEROINIT), Convert.ToUInt32(test.Length))
If p.Equals(IntPtr.Zero) Then
Throw New OutOfMemoryException
Marshal.Copy(test, 0, p, test.Length)
There are several i ues to co ider when determining the case of a Mi ingMethodException. When this exception occurs you should verify the following:
If targeting Pocket PC 2003 use Microsoft eMbedded Visual C++ 4.0.
If targeting Pocket PC 2000 or 2002 use Microsoft eMbedded Visual Tools 3.0
Verify that the parameters to the function match those of the original
A long in native code is typically 32-bits, whereas in the .NET Compact Framework it is 64-bits
Beware of bool
According to MSDN documentation, "Its size is u ecified.":
In a Microsoft ecific section of the MSDN documentation, the bool size is described as varying depending on the version of Visual C++ used to build the binary.:
A BOOL is defined as an int (32-bit value)
.NET Compact Framework Blittable Types:
Non Blittable Types and Marshaling Su ort:
Make sure that the function name is elled correctly
Verify that the DLL is located correctly - Windows or executing folder of target device
Verify with DUMPBIN that the names of the functio were not mangled on exporting of the DLL (extern "C" fixes this). More information on this topic can be found in section
of this FAQ.
Verify that the DLL being imported is not dependant upon other DLLs. A mi ing dependant DLL will result in the Mi ingMethodException.
For the latest Microsoft eMbedded Visual Tools and SDK downloads, visit the MSDN Mobile and Embedded Developer Center "Products &am Updates" download page at:
You can set the system time by P/Invoking the SetSystemTime function.
using System.Runtime.InteropService public struct SYSTEMTIME
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMillisecond }
[DllImport("coredll.dll")]
public extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime);
[DllImport("coredll.dll")]
public extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
// Set the clock ahead one hour
SYSTEMTIME st = new SYSTEMTIME();
GetSystemTime(ref st);
st.wHour = (ushort)(st.wHour + 1 % 24);
SetSystemTime(ref st);
Imports System.Runtime.InteropServices
Public Structure SYSTEMTIME
Public wYear As UInt16
Public wMonth As UInt16
Public wDayOfWeek As UInt16
Public wDay As UInt16
Public wHour As UInt16
Public wMinute As UInt16
Public wSecond As UInt16
Public wMilliseconds As UInt16
End Structure
DllImport("coredll.dll") _
Public Shared Sub GetSystemTime(ByRef lpSystemTime As SYSTEMTIME)
End Sub
DllImport("coredll.dll") _
Public Shared Function SetSystemTime(ByRef lpSystemTime As SYSTEMTIME) As UInt32
End Function
'Set the clock ahead one hour
Dim st As New SYSTEMTIME
GetSystemTime(st)
st.wHour = Convert.ToUInt16(((Convert.ToInt32(st.wHour) + 1)) Mod 24)
SetSystemTime(st)
The device can be soft reset through P/Invoking of the KernelIoControl function, as demo trated in the code below. For more information on how to use the function and extend the functionality of this sample, refer to Visual Studio .NET Help.
On Smartphone devices, this will only work if you are signed with a privileged certificate.
using System.Runtime.InteropService public co t uint FILE_DEVICE_HAL = 0x00000101;
public co t uint METHOD_BUFFERED = 0;
public co t uint FILE_ANY_ACCESS = 0;
public uint CTL_CODE(uint DeviceType, uint Function, uint Method, uint Acce )
return ((DeviceType 16) | (Acce 14) | (Function 2) | Method);
[DllImport("Coredll.dll")]
public extern static uint KernelIoControl
uint dwIoControlCode,
IntPtr lpInBuf,
uint nInBufSize,
IntPtr lpOutBuf,
uint nOutBufSize,
ref uint lpBytesReturned
uint ResetPocketPC()
uint bytesReturned = 0;
uint IOCTL_HAL_REBOOT = CTL_CODE(FILE_DEVICE_HAL, 15,
METHOD_BUFFERED, FILE_ANY_ACCESS);
return KernelIoControl(IOCTL_HAL_REBOOT, IntPtr.Zero, 0,
IntPtr.Zero, 0, ref bytesReturned);
private void Form1_Load(object sender, System.EventArgs e)
DialogResult r = Me ageBox.Show
"Are you sure you want to reset?",
"Test",
Me ageBoxButto .YesNo,
Me ageBoxIcon.Question,
Me ageBoxDefaultButton.Button2
if (r == DialogResult.Yes)
ResetPocketPC();
Public Co t FILE_DEVICE_HAL As Integer = &am H101
Public Co t METHOD_BUFFERED As Integer = 0
Public Co t FILE_ANY_ACCESS As Integer = 0
Public Function CTL_CODE( _
ByVal DeviceType As Integer, _
ByVal Func As Integer, _
ByVal Method As Integer, _
ByVal Acce As Integer) As Integer
Return (DeviceType 16) Or (Acce 14) Or (Func 2) Or Method
End Function 'CTL_CODE
DllImport("Coredll.dll") _
Public Shared Function KernelIoControl _
ByVal dwIoControlCode As Integer, _
ByVal lpInBuf As IntPtr, _
ByVal nInBufSize As Integer, _
ByVal lpOutBuf As IntPtr, _
ByVal nOutBufSize As Integer, _
ByRef lpBytesReturned As Integer _
) As Integer
End Function
Function ResetPocketPC() As Integer
Dim bytesReturned As Integer = 0
Dim IOCTL_HAL_REBOOT As Integer = CTL_CODE(FILE_DEVICE_HAL, _
15, METHOD_BUFFERED, FILE_ANY_ACCESS)
Return KernelIoControl(IOCTL_HAL_REBOOT, IntPtr.Zero, 0, _
IntPtr.Zero, 0, bytesReturned)
End Function 'ResetPocketPC
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
Dim r As DialogResult = Me ageBox.Show( _
"Are you sure you want to reset?", _
"Test", _
Me ageBoxButto .YesNo, _
Me ageBoxIcon.Question, _
Me ageBoxDefaultButton.Button2)
If r = DialogResult.Yes Then
ResetPocketPC()
End Sub 'Form1_Load
This is not su orted with the current version of the .NET Compact Framework. You can, however, P/Invoke Pocket PC's notificaiton system to do this. Refer to the following for more information:
Sample Code:
AYGShell APIs:
The native Notification APIs are: SHNotificationAdd, SHNotificationRemove, SHNotificationGetData, and SHNotificationUpdate.
Refer to the sample in the P/Invoke library.
The Start icon can be hidden using the SHFullScreen API.
co t uint SHFS_SHOWTASKBAR = 0x0001;
co t uint SHFS_HIDETASKBAR = 0x0002;
co t uint SHFS_SHOWSIPBUTTON = 0x0004;
co t uint SHFS_HIDESIPBUTTON = 0x0008;
co t uint SHFS_SHOWSTARTICON = 0x0010;
co t uint SHFS_HIDESTARTICON = 0x0020;
[DllImport("aygshell.dll")]
static extern uint SHFullScreen(IntPtr hwndRequester, uint dwState);
[DllImport("coredll.dll")]
public static extern IntPtr GetCapture();
private void Form1_Load(object sender, System.EventArgs e)
Capture = true;
IntPtr hwnd = GetCapture();
Capture = false;
SHFullScreen(hwnd, SHFS_HIDESTARTICON);
Co t SHFS_SHOWTASKBAR As Integer = &am H1
Co t SHFS_HIDETASKBAR As Integer = &am H2
Co t SHFS_SHOWSIPBUTTON As Integer = &am H4
Co t SHFS_HIDESIPBUTTON As Integer = &am H8
Co t SHFS_SHOWSTARTICON As Integer = &am H10
Co t SHFS_HIDESTARTICON As Integer = &am H20
DllImport("aygshell.dll")
Shared Function SHFullScreen(ByVal hwndRequester As IntPtr, ByVal dwState As Integer) As Integer
End Function
DllImport("coredll.dll")
Public Shared Function GetCapture() As IntPtr
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Capture = True
Dim hwnd As IntPtr = GetCapture()
Capture = False
SHFullScreen(hwnd, SHFS_HIDESTARTICON)
End Sub 'Form1_Load
Refer to the sample:
This sample demo trates how to P/Invoke numerous useful native functio that are not directly available through the .NET Compact Framework. A test Form is provided that enumerates all available test procedures and allows the user to select and run them:
Learn how to use the Waveform Audio Interface to record and play ".wav" files: 7. 通用
使用Reflection,应用程序可以确定自己是从哪个目录启动的,也可以使用IO.Path命名空间来修改它。
using System.Reflectio using System.IO;
// This is the full directory and exe name
String fullA Name = A embly.GetExecutingA embly().GetName().CodeBase;
// This stri off the exe name
String fullA Path = Path.GetDirectoryName(fullA Name);
// This adds a file name to the path
String lashImageName = Path.Combine(fullA Path, "myfile.txt");
Imports System.IO
Imports System.Reflection
' This is the full directory and exe name
Dim fullA Name As String = [A embly].GetExecutingA embly().GetName().CodeBase
' This stri off the exe name
Dim fullA Path As String = Path.GetDirectoryName(fullA Name)
' This adds a file name to the path
Dim lashImageName As String = Path.Combine(fullA Path, "myfile.txt")
学习如何获得程序执行的当前目录。在Embedded Visual Basic中,程序执行的当前目录可以通过A .Path属性获得。执行程序的目录可以通过程序集的A emblyName对象的获得,A emblyName对象包含了程序集的所有描述:
这篇快速入门教程告诉您如何获得您的程序集和数据文件所在的目录。Windows CE .NET本身不支持应用程序的当前目录的设置:
一个应用程序有四种方法得到时间间隔:
System.Environment.TickCount
获得一个带符号的整型值,表示从机器启动到调用时经过的豪秒数。在.NET精简框架下,这个值的误差在0.5秒内,大多情况下会比0.5秒小。
GetTickCount()
属性Environment.TickCount就是调用GetTickCount函数的,所以没有必要再调用本地代码中的这个方法。
Performance Monitor
可以作为压力测试用途,但不是为最终使用的应用程序而设计的。如需更多信息,请查看本问答的 "
使用System.Threading.Timer类,可以在线程内设定计时器,用委托(delegate)指向应用程序 。
Performance Counter
如果OEM厂商支持的话,QueryPerformanceCounter函数能提供最高精度的计时功能。
请查看本问答的"
"章节。
为了能够访问嵌入资源,应用程序只须简单地引用相关的程序集(a embly)并调用GetManifestResourceStream方法。下面这个例子岩石了如何从嵌入资源中建立一个位图:
using System.Reflectio A embly asm = A embly.GetExecutingA embly();
Bitmap bmpSprite = new Bitmap(asm.GetManifestResourceStream("A emblyName.FileName"));
Imports System.Reflection
Dim asm As [A embly] = [A embly].GetExecutingA embly()
Dim bmpSprite As New Bitmap(asm.GetManifestResourceStream("A emblyName.FileName"))
上面代码中, 字符串A emblyName部分可以在运行时通过调用asm.GetName().Name得到。
注意:如果A emblyName中有空格,它将被下划线代替,而且必须这样访问。
这是.net精简框架的BUG。这是由于Windows CE底层的Secure Sockets Layer (SSL)的限制造成的。但是,也偶避免的方法,如果设置 req.AllowWriteStreamBuffering为true,不要设置req.ContentLength属性,那就不会在发生这个错误了。
性能计数器通过编辑设备注册表建立:
建立注册表键:"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework\PerfMonitor"
新建双字节项,值就是计数器的名字。
把Counters的值设置为1表示允许计数器,设置为0表示禁止使用。
设置了性能计数器后,当程序关闭时,会建立一个文本文件"mscoree.stat"。这个文件会存放在设备的根目录。这是一个文件每行的长度是固定的,所以导入Excel是非常方便的。
计数器只能被一个运行着的托管的程序使用。
使用性能计数器时,会导致30%的性能下降。
程序可以重载OnClosing方法,设置CancelEventArgs.Cancel为true就可以取消关闭。
protected override void OnClosing(CancelEventArgs e)
e.Cancel = true;
Protected Overrides Sub OnClosing(ByVal e As CancelEventArgs)
e.Cancel = True
End Sub 'OnClosing
您可以调用本地代码的CreateProce 函数开始运行第二个程序。然后调用本地代码的WaitForSingleObject函数暂停调用的程序,直到第二个程序运行结束。以下快速入门演示了通过PocketPC模拟器来实现这一操作:
一个.net精简框架程序最多会产生4个线程:
一个主应用程序线程。
一个线程控制各种时间间隔,时间间隔是供系统和其他应用程序使用的。
一个线程跟踪活动的TCP/IP接口的变化(模拟Windows XP上的媒体动作,Windows CE上是没有这些操作的)。
一个执行终止对象的线程。当第一个被垃圾回收的对象回收时,就被建立了。
在C++中,通过建造类型(typecasting)可以很方便和有效的保存一个类或结构体到文件,并直接从文件中重构出来。但托管代码的本性决定了它不能这样实现。但还是有办法实现的,建立一个类,把内存中的数据作为它的属性让其他类访问。例如:
public cla MyCla {
protected byte[] m_data = null;
// uint uiDummy
// short sDummy
// This is a bit u afe so you should throw an
// exception or a ert if the byte array length is
// not 6. A safer but le memory efficient a roach
// would be to set m_data = new byte[6] and then copy
//bytes to m_data.
public MyCla (byte[] bytes) {m_data = byte }
// Get/Set the uint
public uint uiDummy
get {return BitConverter.ToUInt32(m_data, 0);}
Buffer.BlockCopy(BitConverter.GetBytes(value),0,m_data,0,BitConverter.GetBytes(value).Length);
// Get/Set the short
public short sDummy
get {return BitConverter.ToInt16(m_data, 4);}
Buffer.BlockCopy(BitConverter.GetBytes(value),0,m_data,4,BitConverter.GetBytes(value).Length);
byte[] fromFile = {1,1,1,1,2,2};
MyCla myCla = new MyCla (fromFile);
uint test1 = myCla .uiDummy; // 0x1010101
short test2 = myCla .sDummy; // 0x202
myCla .sDummy = 0x0505;
// Test setting the short
uint test4 = myCla .uiDummy; // 0x1010101
short test5 = myCla .sDummy; // 0x505
Public Cla ByteCla Protected m_data As Byte() = Nothing
' uint uiDummy
' short sDummy
' This is a bit u afe so you should throw an exception
' or a ert if the byte array length is not 6. A safer
' but le memory efficient a roach would be to set
' m_data = new byte[6] and then copy bytes to m_data.
Public Sub New(ByVal bytes() As Byte)
m_data = bytes
End Sub 'New
' Get/Set the uint
Public Property uiDummy() As UInt32
Return BitConverter.ToUInt32(m_data, 0)
End Get
Set(ByVal Value As System.UInt32)
Buffer.BlockCopy(BitConverter.GetBytes(Value),0,m_data,0,BitConverter.GetBytes(Value).Length)
End Set
End Property
' Get/Set the short
Public Property sDummy() As Short
Return BitConverter.ToInt16(m_data, 4)
End Get
Set(ByVal Value As Short)
Buffer.BlockCopy(BitConverter.GetBytes(Value),0,m_data,4,BitConverter.GetBytes(Value).Length)
End Set
End Property
End Cla 'ByteCla Dim fromFile As Byte() = {1, 1, 1, 1, 2, 2}
Dim testCla As New ByteCla (fromFile)
Dim test1 As System.UInt32 = testCla .uiDummy ' 0x1010101
Dim test2 As Short = testCla .sDummy
' 0x202
testCla .sDummy = &am H505
' Test short
Dim test4 As System.UInt32 = testCla .uiDummy ' 0x1010101
Dim test5 As Short = testCla .sDummy
' 0x505
不可以。在.net精简框架中,只有EventHandler方法可以被调用。以下代码说明啊如何正确使用此方法:
public void HandleMe(object o, EventArgs e) {...}
form.Invoke(new EventHandler(form.HandleMe));
Public Sub HandleMe(o As Object, e As EventArgs)
End Sub 'HandleMe
form.Invoke(New EventHandler(Addre Of form.HandleMe))
Although the following will compile, it will not work properly:
public delegate void MyHandler();
public void HandleMeBadly() {...}
form.Invoke(new MyHandler(form.HandleMeBadly));
Delegate Sub MyHandler()
Public Sub HandleMeBadly()
End Sub 'HandleMeBadly
form.Invoke(New MyHandler(form.HandleMeBadly))
查看这篇文章,学习如何在基于.net精简框架的应用程序中访问***API:
Guid.NewGuid方法可以生成新的GUID,但在.net精简框架中没有此方法。阅读这篇文章,学习如何根据GUID规范在PocketPC应用程序中建立GUID对象:
这篇文章讨论了如何使用InTheHand公司的Pocket Outlook .NET组件:
Visual Studio .NET 2003帮助中的C# Programmer's Reference提供了在.net精简框架下使用不安全代码调用GetFileVersionInfo函数。 这个例子带来的问题是,这个函数是由OEM厂商决定的,并且不保证能返回正确结果。
使用Reflection可以获得程序集(A embly)的版本:
using System.Reflectio String ver = A embly.GetExecutingA embly().GetName().Version.ToString();
Imports System.Reflectio Dim ver As String = [A embly].GetExecutingA embly().GetName().Version.ToString()
使用后台处理,需要注意相关细节并小心设计。这篇文章提供一些关于后台处理最有用的建议,文中介绍的很多观点是必须说明的:
学习如何在基于.net精简框架的Windows窗体应用程序中使用多线程。
学习如何使用PreEmptive Dotfuscator混淆器保护你的代码。
请参考本问答的 "
." 部分。
学习如何使用.net精简框架获得Windows CE设备的设备号。
你可以调用本地代码的函数来获得PocketPC的设备号,也就是序列号。这篇快速入门教程,演示了用Me ageBox来显示设备号。
这篇文章演示了如何从基于.net精简框架的应用程序中发送短消息:
这篇文章讨论了在.net精简框架下如何判断事件的发送者,.net精简框架中的控件不支持name属性:
在应用程序中使用多线程,可以提高用户界面的性能。基类Control提供Invoke、BeginInvoke和EndInvoke方法在控件中来建立线程。.net精简框架不支持异步的BeginInvoke和EndInvoke调用。到现在,也还不支持向同步Invoke调用传递参数。这篇快速入门教程提供一个自定