文档视界 最新最全的文档下载
当前位置:文档视界 › Android Galler2源码分析

Android Galler2源码分析

Android Galler2源码分析
Android Galler2源码分析

图库Gallery2

Gallery2主要功能是实现本地存储器、MTP存储器和网络存储器中媒体(图像和视频)的浏览、显示和更多操作(删除、分享、选择和缩放等)。下面用一张简单的用例图描述了Gallery2的功能和职责。

Gallery 主要是4个页面的跳转:

AlbumSetPage.Java(相册缩略图);

AlbumPage.java(单个相册照片缩略图);

PhotoPage.java(单张照片);

SlideShowPage.java(幻灯片界面);

跳转过程:

AlbumSetPage.Java→AlbumPage.java→PhotoPage.java

SlideShowPage.java是单独的。

这些界面类父类为ActivityState.java;这些界面的切换由StateManager.java负责。

1 界面跳转过程:

在Galley2模块,我们先从程序的入口看起,在androidManifest.xml中注册Application标签(Android 系统会为每个程序运行时创建一个Application的类对象且仅创建一个,他的生命周期等于这个程序的生命周期,它是全局的单实例的,一般做一些全局的初始化操作),应用创建时就会被初始化,维护应用内部全局数据,主要看几个函数:initializeAsyncTask(), GalleryUtils.initialize(this),GalleryUtil是Gallery的工具类,获得了屏幕参数,WindowManager,Resource等

Gallery 从launcher进入Gallery,进入GalleryActivity.ava

@Override

protected void onCreate(Bundle savedInstanceState) {

…...

setContentView(https://www.docsj.com/doc/7b19088351.html,yout.main);

if (savedInstanceState != null) {

getStateManager().restoreFromState(savedInstanceState);

} else {

initializeByIntent();

}

}

private void initializeByIntent() {

Intent intent = getIntent();

String action = intent.getAction();

if (Intent.ACTION_GET_CONTENT.equalsIgnoreCase(action)){ startGetContent(intent);

} else if(Intent.ACTION_PICK.equalsIgnoreCase(action)) { // We do NOT really support the PICKintent. Handle it as

// the GET_CONTENT. However, we needto translate the type

// in the intent here.

Log.w(TAG, "action PICK is notsupported");

String type =Utils.ensureNotNull(intent.getType());

if(type.startsWith("vnd.android.cursor.dir/")) {

if(type.endsWith("/image")) intent.setType("image/*");

if(type.endsWith("/video")) intent.setType("video/*");

}

startGetContent(intent);

} else if(Intent.ACTION_VIEW.equalsIgnoreCase(action)

||ACTION_REVIEW.equalsIgnoreCase(action)){

startViewAction(intent);

} else {

startDefaultPage();

}

}

从这个函数看,如果从相册应用图标进入,会走startDefaultPage流程,如果外部打开图片,会走startGetContent流程。

public void startDefaultPage() {

PicasaSource.showSignInReminder(this);

Bundle data = new Bundle();

data.putString(AlbumSetPage.KEY_MEDIA_PATH,

getDataManager().getTopSetPath(DataManager.INCLUDE_ALL));

getStateManager().startState(AlbumSetPage.class,data);

mVersionCheckDialog =PicasaSource.getVersionCheckDialog(this);

if (mVersionCheckDialog != null) {

mVersionCheckDialog.setOnCancelListener(this);

}

}

这样我们看到的是AlbumSetPage.Java这个界面了。

我们从起始页面开始,点击某个相册:

一个相册是一个SlotView对象,

这里不详细说明SlotView,相关介绍请访问:

https://www.docsj.com/doc/7b19088351.html,/discovery_by_joseph/article/details/17500425

在onCreate()中初始化了SlotView。并且对SlotView进行了监听:

mSlotView.setListener(new SlotView.SimpleListener() {

@Override

public void onDown(int index) {

AlbumSetPage.this.onDown(index);

}

@Override

public void onUp(boolean followedByLongPress) {

AlbumSetPage.this.onUp(followedByLongPress);

}

@Override

public void onSingleTapUp(int slotIndex) {

AlbumSetPage.this.onSingleTapUp(slotIndex);

}

@Override

public void onLongTap(int slotIndex) {

AlbumSetPage.this.onLongTap(slotIndex);

}

});

接下来我们看红色部分:

public void onSingleTapUp(int slotIndex) {

if (!mIsActive) return;

if (mSelectionManager.inSelectionMode()) {

MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);

if (targetSet == null) return; // Content is dirty, we shall reload soon mSelectionManager.toggle(targetSet.getPath());

mSlotView.invalidate();

} else {

// Show pressed-up animation for the single-tap.

mAlbumSetView.setPressedIndex(slotIndex);

mAlbumSetView.setPressedUp();

mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_ALBUM, slotIndex, 0), FadeTexture.DURATION);

}

}

这里发了消息:

消息处理是在onCreate中创建的:

mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {

@Override

public void handleMessage(Message message) {

switch (message.what) {

case MSG_PICK_ALBUM: {

try {

pickAlbum(message.arg1);

} catch (Exception e) {

Log.d(TAG, "exception when pickAlbum");

}

}

default: throw new AssertionError(message.what);

}

}

};

}

private void pickAlbum(int slotIndex) {

if (!mIsActive) return;

......

mActivity.getStateManager().startStateForResult(

AlbumPage.class, REQUEST_DO_ANIMATION, data);

}

@Override

protected void onStateResult(int requestCode, int resultCode, Intent data) {

if (data != null && data.getBooleanExtra(AlbumPage.KEY_EMPTY_ALBUM, false)) {

showEmptyAlbumToast(Toast.LENGTH_SHORT);

}

switch (requestCode) {

case REQUEST_DO_ANIMATION: {

mSlotView.startRisingAnimation();

}

}

}

接收到动作消息,启动相册页面AlbumPage。

后续的进入到单张页面:PhotoPage.java 也是同样的过程,但是我们在代码里看到的是下面:

private void pickPhoto(int slotIndex, boolean startInFilmstrip) {

if (!mIsActive) return;

......

if (startInFilmstrip) {

mActivity.getStateManager().switchState(this, FilmstripPage.class, data);

} else {

mActivity.getStateManager().startStateForResult(

SinglePhotoPage.class, REQUEST_PHOTO, data);

}

}

这里我们看到跳转的是SinglePhotoPage 不是PhotoPage。

我们打开SinglePhotoPage

public class SinglePhotoPage extends PhotoPage {

}

发现他是继承 PhotoPage ,里面什么也没写,所以跳转的还是PhotoPage 。

下面关于SlideShowPage.java(幻灯片界面);这个是怎么跳转的呢?

..........

case R.id.action_slideshow: {

............

mActivity.getStateManager().startStateForResult(

SlideshowPage.class, REQUEST_SLIDESHOW, data);

return true;

}

..............

原来是点击对应菜单选项进入的。

看到这里我们发现在跳转界面的时候都用到了这个函数:

mActivity.getStateManager().startStateForResult( ... , ... , ...);

2.状态管理

这个就是前面提到过的ActivityState.java;也就是说,其实我们看到的只是一个个的ActivityState。而界面的切换是由StateManager.java负责。

我们先来看StateManager.java:里面有个startState(...)函数:

public void startState(Classklass,

Bundle data) {

Log.v(TAG, "startState " + klass);

ActivityState state = null;

try {

state = klass.newInstance();

} catch (Exception e) {

throw new AssertionError(e);

}

if (!mStack.isEmpty()) {

ActivityState top = getTopState();

top.transitionOnNextPause(top.getClass(), klass,

StateTransitionAnimation.Transition.Incoming);

if (mIsResumed) top.onPause();

}

UsageStatistics.onContentViewChanged(

https://www.docsj.com/doc/7b19088351.html,PONENT_GALLERY,

klass.getSimpleName());

state.initialize(mActivity, data);

mStack.push(new StateEntry(data, state));

state.onCreate(data, null);

if (mIsResumed) state.resume();

}

这里用到了java的反射机制去实例化ActivityState。

private Stack mStack = new Stack();

而mStack 就是就是管理我们看到的窗口。

当我们要显示的窗口就放到最上面,其实是个堆栈管理。

而StateEntry这个内部类这是存放当前的ActivityState实例化后的窗口。

通过getTopState();拿到当前显示窗口了。

当然startStateForResult 就是 startState相当于activity的startStateForResult startState;一个可以返回状态,一个不返回。

回退的时候通过重写onBackPressed 方法,退出相应的界面回到上一个界面。

图库VideoPlayer:

对于播放视频来说,只有一个activity ,MovieActivity.java

大致过程:

MovieActivity.java > MoviPlayer > VideoView(MoviePlayerVideoView)

> MedieoPlayer

在MovieActivity

private void initPlayerIfNeed(Intent intent) {

Log.d(TAG, "mPlayer is Create!");

if (mPlayer != null) {

mPlayer.onDestroy();

mPlayer.releaseView(mRootView);

mPlayer = null;

}

mPlayer = new MoviePlayer(mRootView, this, intent.getData(),

mPlayList, mSavedInstanceState, !mFinishOnCompletion) {

@Override

public void onCompletion() {

if (mFinishOnCompletion) {

Log.e(TAG, "XX@@finish when completeXX@@");

finish();

}

}

};

........

}

实例化MoviePlayer,

在 onResume() 中调用 MoviePlayer的onResume()

public void onResume() {

/** SPRD:Bug 474639 add phone call reaction @{ */

boolean isResumeFromPhone = !mIsError && isStreamUri() && mIsPhonePause

&& (mVideoPosition >0);

............

if (mVideoView == null) {

initVideoView();

/** SPRD:Bug 474639 add phone call reaction @{ */

} else if (!isResumeFromPhone || !isTimeOut) {

if (mTimeOutDialog != null && mTimeOutDialog.isShowing()) {

return;

}

mVideoView.resume();

}

................

}

首先初始化MoviePlayer

private void initVideoView() {

mVideoView = (MoviePlayerVideoView) mRootView.findViewById(R.id.surface_view); mVideoView.setOnErrorListener(this);

mVideoView.setOnCompletionListener(this);

........

}

在MoviePlayerVideoView.java

public void resume() {

openVideo();

}

去初始化MediaPlayer

private void openVideo() {

if (mUri == null || mSurfaceHolder == null) {

/** SPRD:not ready for playback just yet, will try again later */

return;

}

..........

/**

* SPRD:we shouldn't clear the target state, because somebody might have called start() * previously

*/

release(false);

try {

mMediaPlayer = new MediaPlayer();

.........

}

致此已经初始化完毕。接下来就可以播放视频了。

播放视频会调用MoviePlayer 的startVideo函数。

private void startVideo() {

// For streams that we expect to be slow to start up, show a

// progress spinner until playback starts.

/**SPRD:Bug517497 video and music play together@{*/

if (mContext != null) {

((AudioManager) mContext.getSystemService(AUDIO_SERVICE))

.requestAudioFocus(null, AudioManager.STREAM_MUSIC,

AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

}

/** @ } */

/**

* SPRD:Bug500699 After waiting for the play after the manual drive,click Start,Continue to play

* video tips modify by old bug429923 @{

*/

mComplete = false;

/** @ } */

Log.e(TAG , "startVideo()");

..................

mVideoView.start();

mVideoView.setVisibility(View.VISIBLE);

................

/**@}*/

}

我们看到会调用mVideoView.start();并显示mVideoView

MoviePlayerVideoView中使用之前已经初始化完成的mMediaPlayer进行播放。

@Override

public void start() {

if (isInPlaybackState()) {

isPlaying = true;// SPRD: add for playing

mMediaPlayer.start();

Log.i(TAG, "start() mMediaPlayer.start()");

mCurrentState = STATE_PLAYING;

}

mTargetState = STATE_PLAYING;

}

这里我们视频播放完成。

界面显示:

在MoviePlayer的构造方法中,我们注意到着一行代码:

mController = new MovieControllerOverlay(mContext);

MovieControllerOverlay这个是我们界面UI,他是extends了CommonControllerOverlay。

而MoviePlayer、CommonControllerOverlay共同实现了ControllerOverlay。ControllerOverlay的listener很好的成为MoviePlayer、MovieControllerOverlay的沟通桥梁。

CommonControllerOverlay.java:

所有的界面元素都是在这个类中初始化。

包括ui隐藏显示,播放、暂停、快进、快退的按钮。

public CommonControllerOverlay(Context context) {

super(context);

mState = State.LOADING;

// TODO: Move the following layout code into xml file.

LayoutParams wrapContent =

new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

LayoutParams matchParent =

new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

/* SPRD: bug 540192,let the layout adapt to the screen @} */

LayoutParams buttonParam = new LayoutParams(

getIntFromDimens(R.dimen.movie_button_size),

getIntFromDimens(R.dimen.movie_button_size));

/* @} */

mBackground = new View(context);

mBackground.setBackgroundColor(context.getResources().getColor(R.color.darker_transparent));

addView(mBackground, matchParent);

mLoadingView = new LinearLayout(context);

mLoadingView.setOrientation(LinearLayout.VERTICAL);

mLoadingView.setGravity(Gravity.CENTER_HORIZONTAL);

ProgressBar spinner = new ProgressBar(context);

spinner.setIndeterminate(true);

mLoadingView.addView(spinner, wrapContent);

TextView loadingText = createOverlayTextView(context);

loadingText.setText(R.string.loading_video);

mLoadingView.addView(loadingText, wrapContent);

addView(mLoadingView, wrapContent);

/** SPRD:Bug474600 improve video control functions @{ */

playControllerView = new LinearLayout(context);

playControllerView.setOrientation(LinearLayout.HORIZONTAL);

playControllerView.setGravity(Gravity.CENTER_HORIZONTAL);

playControllerView.setLayoutParams(wrapContent);

playControllerView.setClickable(true);

/** @} */

/**SPRD:Bug545844 modify by old bug 539690,in Arabic system,the video player back & forward arrows are reversed */

playControllerView.setLayoutDirection(LAYOUT_DIRECTION_LTR);

/** @} */

mPlayPauseReplayView = new ImageView(context);

mPlayPauseReplayView.setImageResource(R.drawable.ic_vidcontrol_play);

mPlayPauseReplayView.setContentDescription(

context.getResources().getString(R.string.accessibility_play_video));

mPlayPauseReplayView.setBackgroundResource(R.drawable.bg_vidcontrol);

mPlayPauseReplayView.setScaleType(ScaleType.CENTER);

mPlayPauseReplayView.setFocusable(true);

mPlayPauseReplayView.setClickable(true);

mPlayPauseReplayView.setOnClickListener(this);

addView(mPlayPauseReplayView, wrapContent);

/** SPRD:Bug474600 improve video control functions @{ */ mStopButView = new ImageView(context);

mStopButView.setImageResource(R.drawable.ic_vidcontrol_stop); /* SPRD: bug 540192,let the layout adapt to the screen @{ */ mStopButView.setScaleType(ScaleType.FIT_CENTER); mStopButView.setLayoutParams(buttonParam);

/* @} */

mStopButView.setFocusable(true);

mStopButView.setClickable(true);

mStopButView.setOnClickListener(this);

mStopButView.setOnClickListener(mStopListener);

mNextVideoView = new ImageView(context); mNextVideoView.setImageResource(R.drawable.ic_vidcontrol_next); /* SPRD: bug 540192,let the layout adapt to the screen @{ */ mNextVideoView.setScaleType(ScaleType.FIT_CENTER); mNextVideoView.setLayoutParams(buttonParam);

/* @} */

mNextVideoView.setFocusable(true);

mNextVideoView.setClickable(true);

mNextVideoView.setOnClickListener(nextListener);

mPrevVideoView = new ImageView(context); mPrevVideoView.setImageResource(R.drawable.ic_vidcontrol_prev); /* SPRD: bug 540192,let the layout adapt to the screen @{ */ mPrevVideoView.setScaleType(ScaleType.FIT_CENTER); mPrevVideoView.setLayoutParams(buttonParam);

/* @} */

mPrevVideoView.setFocusable(true);

mPrevVideoView.setClickable(true);

mPrevVideoView.setOnClickListener(prevListener);

mFfwdButton = new ImageView(context);

/* SPRD: bug 540192,let the layout adapt to the screen @{ */ mFfwdButton.setScaleType(ScaleType.FIT_CENTER); mFfwdButton.setLayoutParams(buttonParam);

/* @} */

mFfwdButton.setFocusable(true);

mFfwdButton.setClickable(true);

mFfwdButton.setOnClickListener(mFfwdListener);

mRewButton = new ImageView(context);

/* SPRD: bug 540192,let the layout adapt to the screen @{ */

mRewButton.setScaleType(ScaleType.FIT_CENTER);

mRewButton.setLayoutParams(buttonParam);

/* @} */

mRewButton.setFocusable(true);

mRewButton.setClickable(true);

mRewButton.setOnClickListener(mRewListener);

ImageView[] btns = new ImageView[]{mPrevVideoView, mRewButton, mStopButView, mFfwdButton, mNextVideoView};

for(int i=0; i

{

LinearLayout buttonLayout=new LinearLayout(context);

buttonLayout.setOrientation(LinearLayout.HORIZONTAL);

buttonLayout.setGravity(Gravity.CENTER);

buttonLayout.setLayoutParams(wrapContent);

buttonLayout.setPadding(0, 20, 0, 0);

buttonLayout.addView(btns[i]);

playControllerView.addView(buttonLayout, wrapContent);

}

addView(playControllerView, wrapContent);

/** @} */

// Depending on the usage, the timeBar can show a single scrubber, or

// multiple ones for trimming.

createTimeBar(context);

addView(mTimeBar, wrapContent);

mTimeBar.setContentDescription(

context.getResources().getString(R.string.accessibility_time_bar));

/** SPRD:bug 474614: porting float play @{ */

Boolean float_window = android.os.SystemProperties.getBoolean(

"persist.sys.floating_window", true);

Log.d(TAG, "float_window = " + float_window);

boolean mIsFloatWindowDisabled = MovieActivity.getInstance().isFloatWindowDisabled();

Log.d(TAG, "mIsFloatWindowDisabled="+mIsFloatWindowDisabled);

if (float_window && !mIsFloatWindowDisabled) {

// old bug info 339523 begin

floatPlayButton = new ImageView(context);

floatPlayButton.setImageResource(R.drawable.ic_media_start_float);

floatPlayButton.setScaleType(ScaleType.CENTER);

floatPlayButton.setFocusable(true);

floatPlayButton.setClickable(true);

floatPlayButton.setOnClickListener(floatPlayListener);

addView(floatPlayButton, wrapContent);

}

// bug 339523 end

/** @} */

mErrorView = createOverlayTextView(context);

addView(mErrorView, matchParent);

https://www.docsj.com/doc/7b19088351.html,youtParams params =

new https://www.docsj.com/doc/7b19088351.html,youtParams(

LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

setLayoutParams(params);

hide();

}

虽说我们初始化了ui控件,但是我们需要固定控件的位置。

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) { ........................................

}

在onLayout中会根据屏幕去计算控件的位置。

protected State mState;

protected enum State {

PLAYING,

PAUSED,

ENDED,

ERROR,

LOADING

}

是控制视频播放时的状态。

经典的串口调试工具源代码(一)

经典的串口调试助手源代码(一) Dim OutputAscii As Boolean Dim InputString As String Dim OutputString As String '============================================================================== ======= ' 变量定义 '============================================================================== ======= Option Explicit ' 强制显式声明 Dim ComSwitch As Boolean ' 串口开关状态判断 Dim FileData As String ' 要发送的文件暂存Dim SendCount As Long ' 发送数据字节计数器 Dim ReceiveCount As Long ' 接收数据字节计数器Dim InputSignal As String ' 接收缓冲暂存 Dim OutputSignal As String ' 发送数据暂存 Dim DisplaySwitch As Boolean ' 显示开关 Dim ModeSend As Boolean ' 发送方式判断

Dim Savetime As Single ' 时间数据暂存延时用Dim SaveTextPath As String ' 保存文本路径 ' 网页超链接申明 Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long Private Sub CloseCom() '关闭串口 On Error GoTo Err If MSComm.PortOpen = True Then MSComm.PortOpen = False ' 先判断串口是否打 开,如果打开则先关闭 txtstatus.Text = "STATUS:COM Port Cloced" ' 串口状态显示 mnuconnect.Caption = "断开串口" cmdswitch.Caption = "打开串口" 'ImgSwitch.Picture = LoadPicture("f:\我的VB\串口调试软件\图片\guan.jpg") ' 显示串口已经关闭 的图标 ImgSwitchoff.Visible = True ImgSwitchon.Visible = False Err: End Sub Private Sub UpdateStatus() If MSComm.PortOpen Then StatusBar1.Panels(1).Text = "Connected" mnuautosend.Caption = "自动发送" mnuconnect.Caption = "断开串口" Else StatusBar1.Panels(1).Text = "断开串口" mnuautosend.Caption = "disautosend" mnuconnect.Caption = "打开串口" End If StatusBar1.Panels(2).Text = "COM" & https://www.docsj.com/doc/7b19088351.html,mPort StatusBar1.Panels(3).Text = MSComm.Settings If (OutputAscii) Then StatusBar1.Panels(4) = "ASCII" Else StatusBar1.Panels(4) = "HEX" End If ' On Error GoTo Err If ChkAutoSend.Value = 1 Then ' 如果有效则,自动发送

Android Hotfix 新方案——Amigo 源码解读

Android Hotfix 新方案——Amigo 源码解读 首先我们先来看看如何使用这个库。 用法 在project 的build.gradle中 dependencies { classpath 'me.ele:amigo:0.0.3' } 在module 的build.gradle中 apply plugin: 'me.ele.amigo' 就这样轻松的集成了Amigo。 生效补丁包 补丁包生效有两种方式可以选择: ? 稍后生效补丁包 ? 如果不想立即生效而是用户第二次打开App 时才打入补丁包,则可以将新的Apk 放到/data/data/{your pkg}/files/amigo/demo.apk,第二次打开时就会自动生效。可以通过这个方法 ? File hotfixApk = Amigo.getHotfixApk(context); ?

获取到新的Apk。 同时,你也可以使用Amigo 提供的工具类将你的补丁包拷贝到指定的目录当中。 ? FileUtils.copyFile(yourApkFile, amigoApkFile); ? ? 立即生效补丁包 ? 如果想要补丁包立即生效,调用以下两个方法之一,App 会立即重启, 并且打入补丁包。 ? Amigo.work(context); ? Amigo.work(context, apkFile); ? 删除补丁包 如果需要删除掉已经下好的补丁包,可以通过这个方法 Amigo.clear(context); 提示:如果apk 发生了变化,Amigo 会自动清除之前的apk。 自定义界面 在热修复的过程中会有一些耗时的操作,这些操作会在一个新的进程中的Activity 中执行,所以你可以通过以下方式来自定义这个Activity。

(通信企业管理)经典串口调试助手源程序及串口通信设置精编

(通信企业管理)经典串口调试助手源程序及串口通 信设置

串口调试助手源程序 及编程详细过程 作者:龚建伟2001.6.20 能够任意转载,但必须注明作者和说明来自https://www.docsj.com/doc/7b19088351.html,,不得作为商用 目次: 1.建立项目 2.于项目中插入MSComm控件 3.利用ClassWizard定义CMSComm类控制变量 4.于对话框中添加控件 5.添加串口事件消息处理函数OnComm() 6.打开和设置串口参数 7.发送数据 如果你仍没有下载源程序,又对本文有兴趣,请立即下载 于众多网友的支持下,串口调试助手从2001年5月21日发布至今,短短壹个月,于全国各地累计下载量近5000人次,于近200多个电子邮件中,20多人提供了使用测试意见,更有50多位朋友提出要串口调试助手的源代码,为了答谢谢朋友们的支持,公开推出我最初用VC控件MSComm编写串口通信程序的源代码,且写出详细的编程过程,姑且叫串口调试助手源程序V1.0或VC串口通讯源程序吧,我相信,如果你用VC编程,那么有了这个代码,就能够轻而易举地完成串口编程任务了。(也许本文过于详细,高手就不用见) 开始吧: 1.建立项目:打开VC++6.0,建立壹个基于对话框的MFC应用程序SCommTest(和我源代码壹致,等会你会方便壹点); 2.于项目中插入MSComm控件选择Project菜单下AddToProject子菜单中的ComponentsandControls…选项,于弹出的对话框中双击RegisteredActiveXControls项(稍等壹会,这个过程较慢),则所有注册过的ActiveX控件出当下列表框中。选择MicrosoftCommunicationsControl,version6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。(如果你于控件列表中见不到MicrosoftCommunicationsControl,version6.0,那可能是你于安装VC6时没有把ActiveX壹项选上,重新安装VC6,选上ActiveX就能够了),

Android源码下载方法详解

Android: Android源码下载方法详解 分类:Android平台 安卓源码下载地址:https://www.docsj.com/doc/7b19088351.html,/source/downloading.html 相信很多下载过内核的人都对这个很熟悉 git clone git://https://www.docsj.com/doc/7b19088351.html,/kernel/common.git kernel 但是这是在以前,现在如果这么执行的话,会显示如下内容 Initialized empty Git repository in /home/star/working/kernel/.git/ https://www.docsj.com/doc/7b19088351.html,[0: 149.20.4.77]: errno=Connection refused fatal: unable to connect a socket (Connection refused) 通过浏览器输入https://www.docsj.com/doc/7b19088351.html,/,发现该网站已经被重定向为 https://www.docsj.com/doc/7b19088351.html,/source/downloading.html 可以在该页面的最后发现内核的下载方法。 下面我们介绍一下Android源码下载的步骤。 工作环境: 操作系统:Ubuntu 10.04 或Ubuntu10.10 git程序:1.7.0.4 或1.7.1 转载请注明出处:https://www.docsj.com/doc/7b19088351.html,/pku_android 方法一: 1.1 初始化安装环境 参考网页https://www.docsj.com/doc/7b19088351.html,/source/initializing.html 主要要做的就是安装jdk和安装一些软件包 $ sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev libc6-dev libncurses5-dev x11proto-core-dev \ libx11-dev libreadline6-dev libgl1-mesa-dev tofrodos python-markdown \ libxml2-utils 如果已经安装了,就不许要这步了 1.2 无论下载内核和源码,都需要进行如下操作 参考网页https://www.docsj.com/doc/7b19088351.html,/source/downloading.html $ mkdir ~/bin $ PATH=~/bin:$PATH $ curl https://https://www.docsj.com/doc/7b19088351.html,/dl/googlesource/git-repo/repo > ~/bin/repo 如果出现: repo init error: could not verify the tag 'v1.12.7',

串口调试助手VC++6.0程序

串口调试助手源程序 及编程详细过程 作者:龚建伟 2001.6.20 可以任意转载,但必须注明作者和说明来自https://www.docsj.com/doc/7b19088351.html,,不得作为商用 目次: 1.建立项目 2.在项目中插入MSComm控件 3.利用ClassWizard定义CMSComm类控制变量 4.在对话框中添加控件 5.添加串口事件消息处理函数OnComm() 6.打开和设置串口参数 7.发送数据 在众多网友的支持下,串口调试助手从2001年5月21日发布至今,短短一个月,在全国各地累计下载量近5000人次,在近200多个电子邮件中,20多人提供了使用测试意见,更有50多位朋友提出要串口调试助手的源代码,为了答谢谢朋友们的支持,公开推出我最初用VC控件MSComm编写串口通信程序的源代码,并写出详细的编程过程,姑且叫串口调试助手源程序V1.0或VC串口通讯源程序吧,我相信,如果你用VC编程,那么有了这个代码,就可以轻而易举地完成串口编程任务了。(也许本文过于详细,高手就不用看) 开始吧: 1.建立项目:打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest(与我源代码一致,等会你会方便一点); 2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的 Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,

Android源代码结构分析

目录 一、源代码结构 (2) 第一层次目录 (2) bionic目录 (3) bootloader目录 (5) build目录 (7) dalvik目录 (9) development目录 (9) external目录 (13) frameworks目录 (19) Hardware (20) Out (22) Kernel (22) packages目录 (22) prebuilt目录 (27) SDK (28) system目录 (28) Vendor (32)

一、源代码结构 第一层次目录 Google提供的Android包含了原始Android的目标机代码,主机编译工具、仿真环境,代码包经过解压缩后,第一级别的目录和文件如下所示: . |-- Makefile (全局的Makefile) |-- bionic (Bionic含义为仿生,这里面是一些基础的库的源代码) |-- bootloader (引导加载器),我们的是bootable, |-- build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具) |-- dalvik (JAVA虚拟机) |-- development (程序开发所需要的模板和工具) |-- external (目标机器使用的一些库) |-- frameworks (应用程序的框架层) |-- hardware (与硬件相关的库) |-- kernel (Linux2.6的源代码) |-- packages (Android的各种应用程序) |-- prebuilt (Android在各种平台下编译的预置脚本) |-- recovery (与目标的恢复功能相关) `-- system (Android的底层的一些库)

VBNET开发全功能串口调试助手

https://www.docsj.com/doc/7b19088351.html, 开发全功能串口调试助手(含完整工程) 小记:https://www.docsj.com/doc/7b19088351.html, 的串口通信用了很长时间了,也只用 Write 和Read 这样的方 法,以前都是用这种方式做上位机软件, 如此足矣。而前几天研究GSM 模块时对 串口返回的数据总是把握不好,参考开发板附送的例程,发现采用 SerialPort 的DataReceived 事件,可以实现中断触发式的数据接收。于是想到要自己做一 个串口调试助手,在实现基本功能的前提下增加一些方便自己调试的功能。 经过 断断续续的编写,就做成了下面这个小软件: 这个软件能够实现串口调试助手的全部功能,经过通信测试,数据接收性能 不亚于呼啸工作室的SComAssistant2.2,通过加大输入缓冲区,可以满足大量 数据接收。 https://www.docsj.com/doc/7b19088351.html, 的串口通信主要使用 VS 自带的SerialPort 控件,而不是早先的 MSComm 更具有兼容性,这也是很久以前就放弃 VB 改用.NET 的直接原因。该控 件的主要方法、属性如下(该数据来自 VS 的MSD 帮助库):

想要通过串口收发数据,就需要对串口进行配置,包括设置端口、波特率、数据格式(如COM端口、9600bps、8位数据位、无校验位、1位停止位)等属性,之后通过Open方法打开串口。打开串口可通过手动指定,也可以使用GetPortNames 方法获取计算机中存在的串口。如果打开出错,则可能是串口不存在或者已被占用。下面是相应代码: Private SubSerialPortOpen() On Error GoToErr If SerialPort.IsOpen = True ThenSerialPort.Close() '避免重复打开端 口 SerialPort.Ope n() LabelCOMStatus.Text ="串口已打开" Exit Sub Err: MsgBox(‘ 串口不存在或已被占用!" + vbNewLine + ErrorToString()) ' 出现错误,显示错误信息 En dSub 如果想要在串口中支持中文字符收发,则可在初始化时设置串口控件的编码: SerialPort.E ncodi ng = System.Text.E ncodi ng.Default 发送数据通过Write方法来完成,由于串口调试助手需要支持文本和16进制, 需要加入转换代码: Private SubButtonSendData_Click( ByVal sender AsSystem.Object, ByVal e AsSystem.EventArgs) Handles ButtonSendData.Click On Error GoToErr

Android USB 驱动分析

Android USB 驱动分析 一、USB驱动代码架构和使用 1、代码简介 USB驱动代码在/drivers/usb/gadget下,有三个文件:android.c, f_adb.c, f_mass_storage.c;g_android.ko 是由这三个文件编译而来,其中android.c 依赖于 f_adb.c 和 f_mass_storage.c(这两个文件之间无依赖关系)。 可在android.c中看到: static int __init android_bind_config(struct usb_configuration *c) { struct android_dev *dev = _android_dev; int ret; printk(KERN_DEBUG "android_bind_config\n"); ret = mass_storage_function_add(dev->cdev, c, dev->nluns); if (ret) return ret; return adb_function_add(dev->cdev, c); } 2、驱动使用 要使USB mass storage连接到主机: 打开/sys/devices/platform/usb_mass_storage/lun0/file文件,向 file文件写入一个存储 设备的路径,例如/dev/block/vold/179:0 (major:minor)路径; 这里的usb_mass_storage根据实际应用可以改的,由 platform_device_register函数的参数决 定。 例如: static struct platform_device fsg_platform_device = { .name = "usb_mass_storage", .id = -1, }; static void __init tegra_machine_init(void) { .... (void) platform_device_register(&fsg_platform_device); .... }

串口调试助手c开发

1.建立项目: 打开VC+ + 6.0,建立一个基于对话框的MFC应用程序SCommTest(与我 源代码一致,等会你会方便一点); 2.在项目中插入MSComm控件 选择Project菜单下Add To Project子菜单中的Componentsand Controls,选项,在弹出的对话框中双击Registered ActiveXControls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。选择Microsoft Communications Control,version6.0,,单击Insert 按钮将它插入到我们的Project 中来,接受缺省的选项。(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX 一项选上,重新安装VC6,选上ActiveX就可以了),这时在ClassView 视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。3.利用ClassWizard定义CMSComm类控制对象 打开ClassWizard- >Member Viariables 选项卡,选择CSCommTestDlg^,为IDC_MSCOMM1添加控制变量:m_ctrlCom m,这时你可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES()#include "mscomm.h" //}}AFX_INCLUDES (这时运行程序,如果有错,那就再从头开始)。 4 .在对话框中添加控件 向主对话框中添加两个编辑框,一个用于接收显示数据ID为 IDC_EDIT_RXDATA另一个用于输入发送数据,ID为IDC_EDIT_TXDAT A再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为 IDC_BUTTON_MANUALSEND别忘记了将接收编辑框的Prop erties->Styles 中把Miltiline和Vertical Scroll属性选上,发送编辑框若你想输入多行文字,也可选上Miltiline。

Android 串口编程原理和实现方式附源码

提到串口编程,就不得不提到JNI,不得不提到JavaAPI中的文件描述符类:。下面我分别对JNI、以及串口的一些知识点和实现的源码进行分析说明。这里主要是参考了开源项目android-serialport-api。 串口编程需要了解的基本知识点:对于串口编程,我们只需对串口进行一系列的设置,然后打开串口,这些操作我们可以参考串口调试助手的源码进行学习。在Java中如果要实现串口的读写功能只需操作文件设备类:即可,其他的事都由驱动来完成不用多管!当然,你想了解,那就得看驱动代码了。这里并不打算对驱动进行说明,只初略阐述应用层的实现方式。 (一)JNI: 关于JNI的文章网上有很多,不再多做解释,想详细了解的朋友可以查看云中漫步的技术文章,写得很好,分析也很全面,那么在这篇拙文中我强调3点: 1、如何将编译好的SO文件打包到APK中?(方法很简单,直接在工程目录下新建文件夹libs/armeabi,将SO文件Copy到此目录即可) 2、命名要注意的地方?(在编译好的SO文件中,将文件重命名为:lib即可。其中是编译好后生成的文件) 3、MakeFile文件的编写(不用多说,可以直接参考package/apps目录下用到JNI的相关项目写法) 这是关键的代码: [cpp]view plaincopy

(二):

文件描述符类的实例用作与基础机器有关的某种结构的不透明句柄,该结构表示开放文件、开放套接字或者字节的另一个源或接收者。文件描述符的主要实际用途是创建一个包含该结构的或。这是API的描述,不太好理解,其实可简单的理解为:就是对一个文件进行读写。 (三)实现串口通信细节 1) 建工程:SerialDemo包名:org.winplus.serial,并在工程目录下新建jni和libs两个文件夹和一个org.winplus.serial.utils,如下图: 2) 新建一个类:SerialPortFinder,添加如下代码: [java]view plaincopy 1.package org.winplus.serial.utils; 2. 3.import java.io.File; 4.import java.io.; 5.import java.io.IOException; 6.import java.io.LineNumberReader; 7.import java.util.Iterator; 8.import java.util.Vector; 9. 10.import android.util.Log; 11. 12.public class SerialPortFinder { 13. 14.private static final String TAG = "SerialPort"; 15.

串口调试助手代码分析42

第5章串口调试助手代码分析 1、建立基于对话框的工程SCOMM 2、绘制界面,如下图: 接收区 串口组合框:IDC_COMBO_COMSELECT,m_Com 波特率组合框:IDC_COMBO_SPEED,m_Speed 停止位组合框:IDC_COMBO_STOPBITS,m_StopBits 数据位组合框:IDC_COMBO_DATABITS,m_DataBits 校验位组合框:IDC_COMBO_PARITY,m_Parity 十六进制显示(接收):IDC_CHECK_HEXRECIEVE,m_ctrlHexReceieve 接收编辑框:IDC_EDIT_RECIVE ,m_ReceiveData m_ctrlReceiveData Style:Vertical Scroll MultiLine 打开串口IDC_BUTTON_OPENPORT,m_ctrlOpenPort 串口开关标志图标IDC _STATIC_OPENOFF,m_ctrlIconOpenoff 数据文件保存路径IDC _EDIT_SA VEPATH,m_strCurPath 保存显示数据文件路径IDC _EDIT_SA VEPATH, m_ctrlSavePath 接收计数IDC_STATIC_RXCOUNT ,m_ctrlRXCOUNT 发送区 …。。。。。。。。。。。。。。 3、添加CSeraiPort类文件 将类文件SerialPort.h SerialPort.cpp 复制到工程所在文件夹中(选择改进

后的类),然后单击VC 6.0菜单Projrct -> Add to Projrct ->Files… ,再在打开的文件选择对话框中选择SerialPort.h 和SerialPort.cpp ,点击OK,就把类文件加入当前工程,并在SCOMMDlg.h 中加入头文件,#include "SerialPort.h",通过上述步骤就在当前工程中加入了CSeraiPort类。 4、完成串口消息处理函数OnCommunicatiom 在CserailPort 类中有多个串口事件可以响应。在一般串口编程中,只需要处理WM_COMM_RXCHAR消息就可以了,该类所有的消息均需要人工添加消息处理函数。我们将处理函数名定义为OnComm()。首先在SCOMMDlg.h 中添加串口字符接收消息WM_COMM_RXCHAR(串口接收缓冲区内有一个字符)响应函数的声明:如下图 然后,在SCOMMDlg.cpp文件中进行WM_COMM_RXCHAR消息映射: 如下图; 接着,在SCOMMDlg.cpp 文件中加入函数OnCommunication(WPARAM ch, LPARAM port)的实现,暂不添加代码。 LONG CSCOMMDlg::OnCommunication(WPARAM ch, LPARAM port) { return 0; } 以上步骤需要手工完成。 至此完成了程序的对话框模板,在工程中插入了串口操作类CserailPort类。5、添加串口初始化及关闭 程序中有两种方法大开串口,一是程序启动,调用OnInitDialog()函数,就可以打开串口,缺省的串口号为COM1,如果COM1不存在或占用,就会给出提示;另外,单击“打开串口”按钮也可以打开串口。 //在初始化中打开串口 BOOL CSCOMMDlg::OnInitDialog() { m_nBaud=9600;//波特率 m_nCom=1;//串口号 m_cParity='N';//奇偶校验

App工程结构搭建:几种常见Android代码架构分析

App工程结构搭建:几种常见Android代码架构分析 关于Android架构,因为手机的限制,目前我觉得也确实没什么大谈特谈的,但是从开发的角度,看到整齐的代码,优美的分层总是一种舒服的享受的。 从艺术的角度看,其实我们是在追求一种美。 本文先分析几个当今比较流行的android软件包,最后我们汲取其中觉得优秀的部分,搭建我们自己的通用android工程模板。 1. 微盘 微盘的架构比较简单,我把最基本,最主干的画了出来: 第一层:com.sina.VDisk:com.sina(公司域名)+app(应用程序名称) 。 第二层:各模块名称(主模块VDiskClient和实体模块entities)第三层:各模块下具体子包,实现类。 从图中我们能得出上述分析中一个最简单最经典的结构,一般在应用程序包下放一些全局的包或者类,如果有多个大的模块,可以分成多个包,其中包括一个主模块。 在主模块中定义基类,比如BaseActivity等,如果主模块下还有子模块,可以在主模块下建立子模块相应的包。说明一点,有的时候如果只有一个主模块,我们完全可以省略掉模

块这一层,就是BaseActivity.java及其子模块直接提至第二层。 在实体模块中,本应该定义且只定义相应的实体类,供全局调用(然而实际情况可能不是这样,后面会说到)。在微盘应用中,几乎所有的实体类是以xxx+info命名的,这种命名也是我赞成的一种命名,从语义上我觉得xxxModel.java这种命名更生动更真实,xxxModel给我一种太机械太死板的感觉,这点完全是个人观点,具体操作中以个人习惯为主。还有一点,在具体的xxxInfo,java中有很多实体类中是没有get/set的方法,而是直接使用public的字段名。这一点,我是推荐这种方式的,特别是在移动开发中,get/set方法很多时候是完全没有必要的,而且是有性能消耗的。当然如果需要对字段设置一定的控制,get/set方法也是可以酌情使用的。 2. 久忆日记 相比于微盘的工程结构,久忆日记的结构稍微复杂了一些。如下图: 1).第一层和前面微盘一样的. 2).第二层则没有模块分类,直接把需要的具体实现类都放在下面,主要日记的一些日记相关的Activity。 3).第二层的实体包命令为model包,里面不仅存放了实体类

串口调试助手C++开发

1.建立项目: 打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest(与我源代码一致,等会你会方便一点); 2.在项目中插入MSComm控件 选择Project菜单下Add To Project子菜单中的 Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX 控件出现在列表框中。选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX一项选上,重新安装VC6,选上ActiveX就可以了),这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。

3.利用ClassWizard定义CMSComm类控制对象 打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时你可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES() #include "mscomm.h" //}}AFX_INCLUDES (这时运行程序,如果有错,那就再从头开始)。 4.在对话框中添加控件 向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。别忘记了将接收编辑框的Properties->Styles中把Miltiline和Vertical Scroll属性选上,发送编辑框若你想输入多行文字,也可选上Miltiline。 再打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg 类,为IDC_EDIT_RXDATA添加CString变量m_strRXData,为

C++课程设计 串口调试助手

目录 【内容摘要】 (2) 【关键词】 (2) 1 开发语言及开发平台简介 (3) 1.1 开发语言 (3) 1.1.1 C语言 (3) 1.1.2 C++语言 (3) 1.2 开发平台 (4) 1.2.1 Microsoft Visual C++ (4) 1.2.2 C++ Builder (5) 2 软件开发过程 (6) 2.1 开发所需要的控件 (6) 2.1.1 按钮控件 (6) 2.1.2 文本控件 (6) 2.1.3 串口控件 (6) 2.1.4 选择控件 (7) 2.2 数据发送设计 (7) 2.3 数据接收设计 (9) 3 软件使用说明 (11) 4 软件测试 (13) 4.1 辅助工具 (13) 4.2 发送测试 (13) 4.3 接收测试 (13) 5 总结 (15) 致谢 (16) 参考文献 (17) 附录主要程序 (18) 串口发送程序 (18) 串口接收程序 (19) 【Abstract】 (21) 【Key Words】 (21)

串口调试助手设计 专业:电子科学与技术学号:XXXXXXXXXXX 学生姓名:X X X 指导老师姓名:X X X 【内容摘要】串口调试助手是串口调试相关工具,网络上有很多串口调试助手,界面不同,功能各异,使用的开发语言和开发平台也不相同。有的使用C语言开发,有的使用C++语言开发,还有的即使用C语言也使用C++语言;开发平台有的使用Visual C++,有的使用C++ Builder等。本软件使用C语言和C++语言,开发平台使用C++Builder软件。该串口调试助手串口调试助手版支持常用的110 ~ 256000bps波特率,能设置校验、数据位和停止位,能以ASCII码或十六进制接收或发送数据或字符(包括中文),能发送文本文件(*.txt 文本),可以任意设定自动发送周期,并能将接收数据保存成文本文件(*.txt),是做项目开发调试串口的好工具。 【关键词】串口;C++;C++ Builder;控件;测试;

最全的Android源码目录结构详解

最全的Android源码目录结构详解 Android 2.1 |-- Makefile |-- bionic (bionic C库) |-- bootable (启动引导相关代码) |-- build (存放系统编译规则及generic等基础开发包配置) |-- cts (Android兼容性测试套件标准) |-- dalvik (dalvik JAVA虚拟机) |-- development (应用程序开发相关) |-- external (android使用的一些开源的模组) |-- frameworks (核心框架——java及C++语言) |-- hardware (部分厂家开源的硬解适配层HAL代码) |-- out (编译完成后的代码输出与此目录) |-- packages (应用程序包) |-- prebuilt (x86和arm架构下预编译的一些资源) |-- sdk (sdk及模拟器) |-- system (底层文件系统库、应用及组件——C语言) `-- vendor (厂商定制代码) bionic 目录 |-- libc (C库) | |-- arch-arm (ARM架构,包含系统调用汇编实现) | |-- arch-x86 (x86架构,包含系统调用汇编实现) | |-- bionic (由C实现的功能,架构无关) | |-- docs (文档) | |-- include (头文件) | |-- inet (?inet相关,具体作用不明) | |-- kernel (Linux内核中的一些头文件) | |-- netbsd (?nesbsd系统相关,具体作用不明) | |-- private (?一些私有的头文件) | |-- stdio (stdio实现) | |-- stdlib (stdlib实现) | |-- string (string函数实现) | |-- tools (几个工具) | |-- tzcode (时区相关代码) | |-- unistd (unistd实现) | `-- zoneinfo (时区信息) |-- libdl (libdl实现,dl是动态链接,提供访问动态链接库的功能)|-- libm (libm数学库的实现,) | |-- alpha (apaha架构) | |-- amd64 (amd64架构) | |-- arm (arm架构) | |-- bsdsrc (?bsd的源码)

VB串口调试助手源代码

VB串口调试助手源代码 Dim OutputAscii As Boolean Dim InputString As String Dim OutputString As String '============================================================================== ======= ' 变量定义 '============================================================================== ======= Option Explicit ’强制显式声明 Dim ComSwitch As Boolean ’串口开关状态判断 Dim FileData As String ’要发送的文件暂存 Dim SendCount As Long ’发送数据字节计数器 Dim ReceiveCount As Long ’接收数据字节计数器 Dim InputSignal As String ’接收缓冲暂存 Dim OutputSignal As String ’发送数据暂存 Dim DisplaySwitch As Boolean ’显示开关 Dim ModeSend As Boolean ’发送方式判断 Dim Savetime As Single ’时间数据暂存延时用 Dim SaveTextPath As String ’保存文本路径 ' 网页超链接申明 Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long Private Sub CloseCom() '关闭串口 On Error GoTo Err If MSComm.PortOpen = True Then MSComm.PortOpen = False’先判断串口是否打开,如果打开则先关闭

基于MSComm控件的串口调试程序及源代码

这是龚建伟老师提供的一个基于MSComm控件的串口调试程序,下面给出了在Visual C++环境下详细的制作过程。附件的源代码是我根据这些步骤编写出来的,可以供大家参考哦! 目录: 1.建立项目 2.在项目中插入MSComm控件 3.利用ClassWizard定义CMSComm类控制变量 4.在对话框中添加控件 5.添加串口事件消息处理函数OnComm() 6.打开和设置串口参数 7.发送数据 8.发送十六进制字符 9.在接收框中以十六进制显示 10.如何设置自动发送 11.什么是VARIANT数据类型?如何使用VARIANT数据类型? 1.建立项目:打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest(与我源代码一致,等会你会方便一点); 2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的 Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX一项选上,重新安装VC6,

选上ActiveX就可以了), 这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls 中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。 3.利用ClassWizard定义CMSComm类控制对象打开ClassWizard ->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时你可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES() #include "mscomm.h" //}}AFX_INCLUDES (这时运行程序,如果有错,那就再从头开始)。 4.在对话框中添加控件 向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。别忘记了将接收编辑框的Properties->Styles中把Miltiline和Vertical Scroll属性选上,发送编辑框若你想输入多行文字,也可选上Miltiline。 再打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg 类, 为IDC_EDIT_RXDATA添加CString变量m_strRXData, 为IDC_EDIT_TXDATA添加CString变量m_strTXData。说明: m_strRXData和m_strTXData分别用来放入接收和发送的字符数据。 5.添加串口事件消息处理函数OnComm() 打开ClassWizard->Message Maps,选择类CSCommTestDlg,选择IDC_MSCOMM1,双击消息OnComm,将弹出的对话框中将函数名改为OnComm,(好记而已)OK。

相关文档
相关文档 最新文档