RSS Feed

Posts Tagged ‘代码’

  1. 改进版的Google 翻译前端

    七月 6, 2009 by bborn

    其实一直对android很感兴趣
    虽然没有用过它的真机…

    上个星期看到了这篇文章
    Android:Google 翻译前端
    作者的代码写的简单明了
    并且发布了源代码给大家学习
    真是很不错

    看了之后 决定动手增加点东西 学习一下android的开发
    增加的内容主要是在查询过程中弹出一个等待的对话框
    涉及到的内容包括 ProgressDialog, AsyncTask
    效果如下
    当用户点击Translate的时候,会出现一个”正在查询”的对话框
    查询完毕后对话框消失

    对话框很好做 showDialog(1) 后
    系统会调用

    @Override
    protected Dialog onCreateDialog(int id) {
    if(1 == id)
    {
    ProgressDialog dialog = new ProgressDialog(GTranslator.this);
    dialog.setTitle(“正在查询”);
    dialog.setMessage(“请稍候……”);
    return dialog;
    }
    return null;
    }

    但是 查询是个阻塞的过程
    我们必须得在另外一个线程里去做这个事情
    比较简单的方法就是继承AsyncTask
    网上有一篇转载比较多的关于AsyncTask的文章(Android线程模型(Painless Threading))
    官方的说明在这里 http://developer.android.com/reference/android/os/AsyncTask.html
    大概说一下 android 的ui线程不是线程安全的
    我们不能在其他的线程里直接做关于ui的操作
    这里有个简单的办法就是继承AsyncTask
    然后实现它的doInBackground方法
    在类的onPreExecute(),publishProgress(Progress…),onPostExecute(Result)方法里
    做ui的操作
    如果在doInBackground里操作ui
    可能会弹出异常提示
    “Only the original thread that created a view hierarchy can touch its views”
    不是每次都弹…为什么了?

    下面贴一下线程的代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    
    	private class ProcessDialogThread extends AsyncTask<String, Void, String> {
    		// @Override
    		protected String doInBackground(String... str) {
     
    			String toTranslateTextString = toTranslateEditText.getText()
    					.toString();
    			String tempString = toTranslateTextString.replace(" ", "%20");
    			fromString = mCountries[fromSpinner.getSelectedItemPosition()];
    			toString = mCountries[toSpinner.getSelectedItemPosition()];
    			String queryString = tempString + "&langpair=" + fromString + "%7C"
    					+ toString;
     
    			return getRawData(queryString);
    		}
     
    		protected void onPreExecute() {
    			showDialog(1);
    			translatedTextView.setText("Connecting...");
    		}
     
    		protected void onPostExecute(String rawData) {
    			dismissDialog(1);
    			if (null != rawData) {
    				String parsedDataString = getData(rawData);
    				if (null == parsedDataString || "" == parsedDataString) {
    					try {
    						translatedTextView.setText("Not found");
    					} catch (Exception e) {
    						e.printStackTrace();
    					}
    				} else {
    					translatedTextView.setText(parsedDataString);
    					dbAdapter.insertItem(toTranslateEditText.getText()
    							.toString(), parsedDataString);
     
    					/*
    					 * FileAccess.writeFile(this,
    					 * toTranslateEditText.getText().toString() + ":" +
    					 * parsedDataString);
    					 */
    				}
    			} else {
    				translatedTextView.setText("Translate failed!");
    			}
    		}
     
    		public String getRawData(String string) {
    			String dataString = null;
    			// String queryString = "hello%20world&langpair=en%7Czh-CN";
    			String queryString = string;
    			try {
    				URL url;
    				if (bAtOffice) {
    					url = new URL("http://10.85.40.153:8000/a.xml");
    				} else {
    					url = new URL(
    							"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q="
    									+ queryString);
    				}
     
    				URLConnection conn = url.openConnection();
    				conn.connect();
    				BufferedReader reader = new BufferedReader(
    						new InputStreamReader(conn.getInputStream()));
     
    				byte buffer[] = new byte[1024];
     
    				// bis.r
    				String readerString;
    				while ((readerString = reader.readLine()) != null) {
    					dataString += readerString;
    				}
     
    				reader.close();
    				// is.close();
     
    			} catch (IOException e) {
    				System.out.print("Net work error");
    			}
    			return dataString;
    		}
    	}

  2. 在windows平台编译FFMPEG的静态链接库

    十一月 7, 2008 by bborn

    这篇日志记录了我编译ffmpeg和x264的经历
    包括我遇到的问题,想到的方法,解决的思路和办法
    我的环境是windows平台下,使用最新的代码
    在vc2005下的工程中静态链接使用

    这几天一直在琢磨H264的解码库
    因为之前用的从ffmpeg提取出来的代码比较老
    在某些情况下会crash
    也是ffmpeg工程组论坛上找到了
    hust_xcl 提取的解码代码(看id应该是校友呢)
    我使用它解出来的图像马赛克现象非常严重
    并且有比较多的内存泄露
    权衡了半天
    决定还是自己动手吧

    目前开源的h264的解码大概都是在用ffmpeg
    不止是h264, 包括各种视频的解码及转码
    那些视频网站的后台可能都是跑着ffmpeg
    他是个很强大的库
    但是在windows平台的编译却很麻烦
    先让我发会牢骚 不吐不快
    首先,搜索到的国内的资料基本都是抄,转载
    链接的网址都无效了
    有些概念我认为是错误的
    ffmpeg工程组论坛似乎只有admin一个人回帖
    很多问题之后都不了了之
    即使解决了也不贴出解决方案
    而且一些问题的解决的方法
    都是知其然不知其所以然
    不分享 不深究
    这种态度不行啊
    (更多…)


  3. 全排列

    十一月 17, 2006 by bborn

    题目:写一个函数, 如 Foo(const char *str), 打印出 str 的全排列,
    如 abc 的全排列: abc, acb, bca, dac, cab, cba

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    
    #include “stdafx.h”
    #include <iostream>
    #include <iterator>
    #include <string>
    #include <vector>
    #include <algorithm>
    using namespace ::std;
    void Foo(const char *str);           //stl
    void Foo2(const char *str);          //recursion
    void foo2( char *str,int position,int strlen ,int &count);
    void Foo3(const char *str);          //loop
    int main(int argc, char *argv[])
    {
    unsigned long start = ::GetTickCount();
    Foo(”abcdefg”);
    unsigned long end = ::GetTickCount();
    unsigned long worktime1 = end - start;
    start = ::GetTickCount();
    Foo2(”abcdefg”);
    end = ::GetTickCount();
    unsigned long worktime2 = end - start;
    start = ::GetTickCount();
    Foo3(”abcdefg”);
    end = ::GetTickCount();
    unsigned long worktime3 = end - start;
    cout< <”use stl time =<<worktime1 <<endl;
    cout<<”use recursion time =<<worktime2 <<endl;
    cout<<”use loop time =<<worktime3 <<endl;
    system(”pause”);
    return 0;
    }
    void Foo(const char *str)
    {
    int n=strlen(str),count=0;
    vector<char> a(n);
    for(int i=0; i<n ; i++)
    a[i]=str[i];
    vector<char>::iterator start, end;
    ostream_iterator<char> outIt(cout, “”);
    start = a.begin();
    end = a.end();
    do {
    count++;
    copy(start, end, outIt) ;
    cout < < endl ;
    } while(next_permutation(start, end));
    cout<<count<<endl;
    }
    void Foo2(const char *str)
    {
    int n=strlen(str),count=0;
    char *mystr = (char *)malloc(n*sizeof(char));
    memcpy(mystr , str ,n);
     
    foo2(mystr , 0 , n ,count);
    cout<<count<<endl;
    free(mystr);
    }
    void foo2(char *str,int position,int strlen ,int &count)
    {
    if(position == strlen)
    {
    cout<<str<<endl;
    count ++;
    }
    else
    {
    for(int i = position; i < strlen; i++)
    {
    swap(*(str + i) , *(str + position));
    foo2(str,position+1,strlen,count);
    swap(*(str + i) , *(str + position));
    }
    }
    }
    void Foo3(const char *str)
    {
    int len = strlen(str);
    int * range = new int[len];
    int cont, i, j, counter = 0;
    memset(range, 0, len*sizeof(int));
    while(1)
    {
    for(i=0; i<len; i++)
    {
    if(++range[i]>=len)
    range[i] = 0;
    else
    break;
    }
    if (i==len)
    {
    break;
    }
    for(i=0,cont=0; i<len -1; i++)
    {
    for(j=i+1; j<len; j++)
    {
    if(range[i] == range[j])
    {
    cont=1;
    break;
    }
    }
    if (cont == 1)
    {
    break;
    }
    }
    if (cont) continue;
    for(i=0; i<len; i++)
    {
    printf(%c”, str[range[i]]);
    }
    printf(”n”);
    ++counter;
    }
    delete [] range;
    cout<<counter<<endl;
    }

    据说是迅雷的一个笔试题目,这给了三种方法,第一种用库函数,当然这是一个玩笑.第二使用的递归,第三使用的是循环,第三个的思路比较特别,生成一个不重复的数列,一般的比较,递归是比较快的一种方法,其次是循环.这些代码都是来自csdn的讨论,我做了些修改和优化.还有,在stdafx.h中加入 #include "Windows.h",没有考虑有重复字符的问题


  4. 网络词霸

    六月 15, 2006 by bborn

    大概两个月前 帮别人有偿做了一个软件
    通过网络查询英文单词
    可以查询英语单词和汉语词汇
    界面做的很简单
    原理大概就是用过网络查询
    之后获得网页 从网页中提取有用的信息
    稍微麻烦的就是网页有三个
    要从第一个网页中得到另外两个网址
    然后再获取 获取的方法是用通常的对字符串的处理
    而不是正则表达式 发现这个在处理这种类型的问题时候很不灵活
    效率也差些
    之前先有人说服务器那边会对查询来路进行
    因而用软件不能查询 并用java写了例程
    其实这个很好解决
    可能他是用”oop”用惯了

    CString getweb(CString word)
    {
    CString output;

    CInternetSession session(“MySession”);
    CHttpConnection* conn = NULL;
    CHttpFile* file = NULL;

    conn = session.GetHttpConnection(“www.dreye.com.cn”, (INTERNET_PORT)8080);

    CString strPost = word;

    file = conn->OpenRequest(CHttpConnection::HTTP_VERB_POST,_T(“/axis/ddict.jsp”));
    file->AddRequestHeaders(“Content-Type: application/x-www-form-urlencoded”);
    file->AddRequestHeaders(“Referer: http://www.dreye.com.cn/”); //服务器识别来路
    file->AddRequestHeaders(“Accept-Language : zh-cn”);
    file->SendRequest(NULL,0,(LPVOID)(LPSTR)(LPCTSTR)strPost,strPost.GetLength());
    CString strRead;

    while(file->ReadString(strRead))
    {
    output+=strRead;
    }

    return output;

    }

    呵呵 看到是哪个网站了吧
    从网页中提取信息的代码

    CString formatweb(CString html)
    {
    CString output;

    html.Replace(”

    html.Replace(”
    “,”\r\n”);

    int start=html.Find(”

    “);
    if (start==-1)
    {
    start=html.Find(”

    “);
    }
    int end=html.Find(“

    “);

    bool ifskip = true;
    for(int i=start;i
    {
    if(html.GetAt(i)==’<’)
    ifskip=true;
    if(html.GetAt(i)==’>’)
    {
    ifskip=false;
    continue;
    }
    if(ifskip)
    continue;

    output+=html.GetAt(i);
    }
    return output;

    }

    思路就是先找到信息的开头和结尾
    把中间的换行替换为”\r\n”
    之后再过滤掉html标签中的东西就是了
    不过需要说明的是三个网页信息的提取并不是一样的
    有个还是需要小小改动一下的 道理是一样的

    主要代码就是这样
    其实那网站想要封掉可以很简单的更换样式表就可以
    这个当时花了我大概一天是时间去弄他
    还是挺好玩的


  5. 用鼠标手势动作来发送命令

    六月 7, 2006 by bborn

    这个大概也是两三年前的代码
    发到了vckbase中的
    http://www.vckbase.com/document/viewdoc/?id=805
    —————————————-
    在一些比较不错的浏览器中,出现了一些新的功能,通过鼠标动作(也称鼠标手势Mouse Gestures)来发出一些命令,比如opera,myie2.一般是这样,先按住鼠标右键,不要松,然后画直线或者其他设定的路径,就可以完成指定的命令。下面我们就来实现这个功能,具体的核心代码来自共享软件联盟小树冲浪浏览器中,整理改编了其中的一些地方。

    1.建立一个对话框程序,声明以下变量和函数

    [code] BOOL m_bIsCapture;//一个标志变量
    char m_MouseGestures[4], m_SeqMG[4];//用来保存鼠标动作的代码U(上) D(下)等..
    int m_iMGLen;
    int m_iMouseGS, m_iMouseGE;
    POINT m_StartPoint; //鼠标的坐标点

    BOOL MoveDirection(CPoint& point, char* Direction); //判断鼠标的简单动作,四个,上下左右
    void PushMouseGesture(char gesture);//把鼠标动作的代码保存起来[/code]

    2.在对话框中加一个文本框,增加它的CString变量,m_mouse,用来显示鼠标的动作

    3.重载OnMouseMove的函数,如下
    [code]if( nFlags == MK_RBUTTON) //判断时候鼠标右键按下
    {
    if (m_bIsCapture) //初始的值的TRUE, 只有当第一点的时候发生里面的动作
    {
    m_bIsCapture=FALSE;
    SetCapture(); //捕获鼠标
    m_StartPoint = point; //记录初始坐标点
    }
    char dir;
    if(MoveDirection(point, &dir)) //调用函数
    {
    PushMouseGesture(dir);
    m_StartPoint = point;
    }
    }
    CDialog::OnMouseMove(nFlags, point);
    } [/code]

    4.判断鼠标动作的函数 (核心),个人认为是很巧妙而且简单的算法:
    [code]BOOL Cmouse2Dlg::MoveDirection(CPoint &point, char *Direction)
    {
    int x = point.x - m_StartPoint.x;
    int y = point.y - m_StartPoint.y;
    int dist = x*x+y*y;
    if(dist>64)
    {
    if(x>abs(y) && x>0)
    *Direction = RBUT_RIGHT;
    else if(abs(x)>abs(y) && x<0)
    *Direction = RBUT_LEFT;
    else if(y>abs(x) && y>0)
    *Direction = RBUT_DOWN;
    else if(abs(y)>abs(x) && y<0)
    *Direction = RBUT_UP;
    else
    return FALSE;
    return TRUE;
    }
    else
    return FALSE;
    }[/code]

    5.PushMouseGesture函数

    这个函数主要是将鼠标的动作保存到m_MouseGestures中,等以后调用
    [code]if(m_iMouseGE!=0 || m_iMouseGS !=0) //m_iMouseGS和m_iMouseGE初始为0
    {
    int pre = (m_iMouseGE -1 + m_iMGLen)m_iMGLen;
    if(m_MouseGestures[pre] == gesture)
    return;
    }
    m_MouseGestures[m_iMouseGE] = gesture;
    m_iMouseGE = (m_iMouseGE+1)m_iMGLen;
    if(m_iMouseGS == m_iMouseGE)
    m_iMouseGS = (m_iMouseGS + 1)m_iMGLen;[/code]

    6.重载OnRButtonUp函数,这是最后触发的动作,命令处理都在这里

    [code]if(!m_bIsCapture) //看标志变量,是否触发了鼠标动作
    { m_bIsCapture=TRUE;
    ReleaseCapture();

    int i =0; m_SeqMG[0]= ''\0'';
    while(m_iMouseGE != m_iMouseGS) //将鼠标动作保存到m_SeqMG中,并在最后加上\0
    {
    m_SeqMG[i] = m_MouseGestures[m_iMouseGS];
    i++;
    m_SeqMG[i] = ''\0'';
    m_iMouseGS = (m_iMouseGS +1)m_iMGLen;
    }

    if(i>0) //开始比较鼠标动作,在这里可以加上自定义的动作和命令!
    {
    if(strcmp(m_SeqMG, "D")==0)
    m_mouse="Down";
    else if(strcmp(m_SeqMG, "L")==0)
    m_mouse="Left";
    else if(strcmp(m_SeqMG, "U")==0)
    m_mouse="Up";
    else if(strcmp(m_SeqMG, "R")==0)
    m_mouse="Right";
    else if(strcmp(m_SeqMG, "UD")==0)
    m_mouse="Up Down";
    else if(strcmp(m_SeqMG, "RLR")==0)
    m_mouse="Right Left Right";
    else if(strcmp(m_SeqMG, "UL")==0)
    m_mouse="Up Left";
    else if(strcmp(m_SeqMG, "UR")==0)
    m_mouse="Up Right";
    else {
    m_mouse="";
    i = 0;
    }
    }
    UpdateData(FALSE);
    }[/code]

    7.在文档试图程序中是差不多的过程,可以自己试试.
    8.opera 的鼠标动作介绍网址:http://www.opera.com/features/mouse/
    myie2的鼠标手势介绍网址:http://www.myie2.com/html_chs/tour/02mousegesture.htm


  6. 使用CFtpFileFind和递归算法来遍历ftp目录

    五月 21, 2006 by bborn

    大概是2003年 我发在vckbase上的一篇小文章
    03年啊 好久了
    原文地址 http://www.vckbase.com/document/viewdoc/?id=734
    ———————————————————————————————-
    微软提供了一个WinInet网络编程接口,可以让程序员在较高层次建立Internet客户应用程序.封装了Winsock API 来简化网络编程过程. 使用WinInet提供的十二个类中的一些,使程序员不需要了解Windows套接字的细节,只要几个函数既可完成链接和一些功能.这里给出一个简单的例子,来遍历一个ftp所有的文件,并输出一个有层次的列表.

    首先建立一个对话框的程序,其中加入五个文本编辑框,分别用来输入ftp地址,端口,用户名,密码,和输出列表.再加入一个按钮.分别加入变量如下:

    CString m_host; //ftp地址
    CString m_username;//用户名
    CString m_password;//密码
    int m_port;//端口
    CString m_ftpinfo;//输出的消息

    同时还需要在头文件中加入如下几个变量: CInternetSession *m_pInetSession;//WinInet类之一,创建并初始化Internet会话
    CFtpConnection *m_pFtpConnection;//建立Ftp连接
    int n;//用来产生层次的ftp输出目录,因为要重复使用,所以在这里定义
    再定义一个遍历函数
    afx_msg void List();
    ok! 头文件到此为止.
    在初始化函数中,设置 n=0;
    添加按钮的事件,

    void Cmfcftp3Dlg::OnBnClickedButton1()
    {
    m_pInetSession=new CInternetSession(AfxGetAppName(),1,PRE_CONFIG_INTERNET_ACCESS);
    UpdateData(TRUE);

    try
    {
    m_pFtpConnection=m_pInetSession->GetFtpConnection(m_host,m_username,m_password,m_port);

    if (m_pFtpConnection != NULL)

    {
    CString m_i;
    m_i=”连接成功\r\n”;
    m_ftpinfo +=m_i;
    UpdateData(FALSE);
    List();
    }
    }
    catch (CInternetException * pEx)
    {
    CString m_i;
    m_i=”连接no成功\r\n”;
    m_ftpinfo +=m_i;
    UpdateData(FALSE);
    TCHAR szError[1024];
    if ( pEx->GetErrorMessage(szError,1024))
    {

    m_i=(CString) szError;
    m_ftpinfo +=m_i;
    UpdateData(FALSE);
    }
    else
    AfxMessageBox(“There was an exception”);
    pEx->Delete();
    m_pFtpConnection=NULL;
    }
    }

    上面的是个简单又标准的连接方法.真正的核心在下面:

    void Cmfcftp3Dlg::List()
    {
    CString m_i;
    CString m_ii;//用来保存一些临时信息
    CStringArray m_Dir;//用数组来保存目录
    CFtpFileFind finder(m_pFtpConnection);
    BOOL bWorking=finder.FindFile(_T(“*”));

    while (bWorking)
    {
    bWorking = finder.FindNextFile();
    if ( finder.IsDots() ) continue;
    if (finder.IsDirectory())
    {
    m_Dir.Add( finder.GetFileName());//如果是目录的话,就保存在数组里
    }
    else
    {
    m_i=finder.GetFileName()+”\r\n”;//如果不是目录的话,就先显示出来
    for (int j=0;j
    {
    m_ii=”\t”;
    m_ftpinfo=m_ftpinfo+m_ii;
    }
    m_ftpinfo +=m_i;
    UpdateData(FALSE);
    }
    }
    finder.Close(); //连接关闭
    for(int i=0;i
    {

    n++;
    m_i=”["+m_Dir.GetAt(i)+"]“+”\r\n”; //在目录的名字外面加上[]

    for (int j=1;j
    {
    m_ii=”\t”;
    m_ftpinfo=m_ftpinfo+m_ii;
    }
    m_ftpinfo +=m_i; //先显示目录的名字
    UpdateData(FALSE);

    BOOL m_suc=0;
    while (!m_suc) //进入目录里面
    {
    m_suc=m_pFtpConnection->SetCurrentDirectory(m_Dir.GetAt(i));
    }

    List(); //递归调用!
    BOOL m_suc1=0;
    while(!m_suc1)
    {
    m_suc1= m_pFtpConnection->SetCurrentDirectory(“..”);
    }
    n–; //控制层次的
    }
    }

    这里有个问题就是关于CFtpFileFind的调用,不能同时有两个CFtpFileFind的函数存在,
    否则会出错,这也是为什么要用数组保存的原因! 对此msdn的解释是:

    ERROR_FTP_TRANSFER_IN_PROGRESS
    The requested operation cannot be made on the FTP session handle because an
    operation is already in progress.

    需要改进的地方,一个是线程的问题,遍历很占用资源,所以最后专门用个线程来.
    再,一是可能是递归效率的问题,一可能是WinInet的问题,当需要遍历的目录比较多或者深的时候,
    可能会出现程序显示没有响应.

    其他: 刚好今天收到一位csdn上的朋友的信,告诉我他的解决方法.大同小异,一起附上,但没有测试.
    来自nicky:

    void ExpoloerDir(CString strDir) {
    CFtpFileFind finder(pFtp);
    CString filename;
    CStringList list;

    m_pFtp->SetCurrentDirectory(strDir);
    bool bContinue=(bool)finder.FindFile(“*”);
    while(bContinue) {
    bContinue=finder.FindNextFile();
    filename=finder.GetFileName();
    if(filename==”.”||filename==”..”)
    continue;
    if(finder.IsDirectory()==true)
    list.AddTail(filename);
    }
    finder.close();

    while(list.IsEmpty()==false) {
    strDir=list.RemoveHead();
    ExplorerDir(strDir);
    }
    }