dlutyuanhongl(乱石铺街)的BLOG

VC知识库BLOG 首页 新随笔 联系 聚合 登录
  11 Posts :: 1 Stories :: 72 Comments :: 2 Trackbacks

留言簿(8)

随笔分类

随笔档案

文章分类

文章档案

相册

搜索

最新评论

阅读排行榜

评论排行榜

2005年5月1日 #

《易经》第一卦 乾 乾为天 乾上乾下

  乾:元,亨,利,贞。

  初九:潜龙,勿用。

  九二:见龙再田,利见大人。

  九三:君子终日乾乾,夕惕若,厉无咎。

  九四:或跃在渊,无咎。

  九五:飞龙在天,利见大人。

  上九:亢龙有悔。

  用九:见群龙无首,吉。

彖曰:大哉乾元,万物资始,乃统天。云行雨施,品物流形。大明始终,六位时成,时乘六龙以御天。乾道变化,各正性命,保合大和,乃利贞。首出庶物,万国咸宁。

象曰:天行健,君子以自强不息。

潜龙勿用,阳在下也。 见龙再田,德施普也。 终日乾乾,反复道也。 或跃在渊,进无咎也。飞龙在天,大人造也。 亢龙有悔,盈不可久也。 用九,天德不可为首也。

文言曰:「元者,善之长也,亨者,嘉之会也,利者,义之和也,贞者,事之干也。 君子体仁,足以长人;嘉会,足以合礼;利物,足以和义;贞固,足以干事。 君子行此四者,故曰:乾:元亨利贞。」

初九曰:「潜龙勿用。」 何谓也?

子曰: 「龙德而隐者也。不易乎世,不成乎名;世而无闷,不见是而无闷;乐则行之,忧则违之;确乎其不可拔,乾龙也。」

九二曰:「见龙在田,利见大人。」 何谓也?

子曰: 「龙德而正中者也。 庸言之信,庸行之谨,闲邪存其诚,善世而不伐,德博而化。 易曰:「见龙在田,利见大人。」 君德也。」

九三曰:「君子终日乾乾,夕惕若,厉无咎。」 何谓也?

子曰: 「君子进德修业,忠信,所以进德也。修辞立其诚,所以居业也。知至至之,可与几也。 知终终之,可与存义也。 是故,居上位而不骄,在下位而不忧。故乾乾,因其时而惕,虽危而无咎矣。」

九四:「或跃在渊,无咎。」 何谓也?

子曰: 「上下无常,非为邪也。 进退无恒,非离群也。 君子进德修业,欲及时也,故无咎。」

九五曰:「飞龙在天,利见大人。」 何谓也?

子曰: 「同声相应,同气相求;水流湿,火就燥;云从龙,风从虎。 圣人作,而万物睹,本乎天者亲上,本乎地者亲下,则各从其类也。

上九曰:「亢龙有悔。」 何谓也?

子曰: 「贵而无位,高而无民,贤人在下而无辅,是以动而有悔也。」

乾龙勿用,下也。 见龙在田,时舍也。 终日乾乾,行事也。或跃在渊,自试也。飞龙在天,上治也。 亢龙有悔,穷之灾也。乾元用九,天下治也。

乾龙勿用,阳气潜藏。见龙在田,天下文明。终日乾乾,与时偕行。 或跃在渊,乾道乃革。飞龙在天,乃位乎天德。亢龙有悔,与时偕极。 乾元用九,乃见天则。

乾元者,始而亨者也。 利贞者,性情也。 乾始能以美利利天下,不言所利。 大矣哉!大哉乾乎?刚健中正,纯粹精也。 六爻发挥,旁通情也。 时乘六龙,以御天也。 云行雨施,天下平也。君子以成德为行,日可见之行也。潜之为言也,隐而未见,行而未成,是以君子弗用也。
   君子学以聚之,问以辩之,宽以居之,仁以行之。易曰:「见龙在田,利见大人。」 君德也。

九三, 重刚而不中,上不在天,下不在田。 故乾乾,因其时而惕,虽危无咎矣。

九四, 重刚而不中,上不在天, 下不在田,中不在人,故或之。或之者,疑之也,故无咎。

夫大人者,与天地合其德,与日月合其明,与四时合其序,与鬼神合其吉凶。 先天下而天弗违,后天而奉天时。 天且弗违,而况於人乎? 况於鬼神乎?

亢之为言也,知进而不知退,知存而不知亡,知得而不知丧。

其唯圣人乎? 知进退存亡,而不失其正者,其为圣人乎?

发表于 2005-05-01 18:37 乱石铺街 阅读(2705) | 评论 (5)编辑 收藏

2005年4月25日 #

        连续闭门写了十几天代码,亦没有任何进展。索性就不弄了,看了一晚上央视版《水浒》。我怎么越看宋江越恶心,不像个N多人的头领。
发表于 2005-04-25 20:09 乱石铺街 阅读(2534) | 评论 (8)编辑 收藏

2005年4月19日 #

    最近要做一个网络方面的小东东,基于C/S模式的。都说IOCP可以使系统达到最佳的性能,因此我就比划了两下,献丑了。抄书开始。
    从本质上说,完成端口模型要求创建一个windows完成端口对象,该对象通过指定数量的线程,对重叠I/O请求进行管理,以便为已经完成的重叠I/O请求提供服务。
    首先要创建一个I/O完成端口对象,用它面向任意数量的套接字句柄,管理多个I/O请求。调用以下函数创建完成端口对象:

HANDLE CreateIoCompletionPort(
  HANDLE FileHandle,// 同IOCP关联在一起的套接字句柄
  HANDLE ExistingCompletionPort,// IOCP句柄
  ULONG_PTR CompletionKey,        // 完成健
  DWORD NumberOfConcurrentThreads // 在IOCP上,同时允许执行的线程数量
);

    该函数有两个作用:
    (1)创建一个完成端口对象
    (2)将一个句柄同完成端口关联到一起
    
    然后就要创建一定数量的工作者线程,以便在套接字的I/O请求投递给完成端口后,为完成端口提供服务。写文字描述很烦,还是看代码吧:

// NetServer3.cpp : Defines the entry point for the console application.
//

#include 
"stdafx.h"
#include 
"NetServer3.h"

#include 
<winsock2.h>
#pragma comment(lib, 
"ws2_32.lib")

#include 
<iostream>
using namespace std;

//////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//////////////////////////////////////////////////////////////////////////

// 单句柄数据
typedef struct tagPER_HANDLE_DATA
{
    SOCKET Socket;
    SOCKADDR_STORAGE ClientAddr;
    
// 将和这个句柄关联的其他有用信息,尽管放在这里面吧
}
PER_HANDLE_DATA, *LPPER_HANDLE_DATA;

// 但I/O操作数据
typedef struct tagPER_IO_DATA
{
    OVERLAPPED Overlapped;
    WSABUF DataBuf;
    
char buffer[1024];
    
int BufferLen;
    
int OperationType;   // 可以作为读写的标志,为简单,我忽略了
}
PER_IO_DATA, *LPPER_IO_DATA;

DWORD WINAPI ServerWorkerThread(LPVOID lpParam);

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    
int nRetCode = 0;

    
// initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    
{
        
// TODO: change error code to suit your needs
        cerr << _T("Fatal Error: MFC initialization failed"<< endl;
        nRetCode 
= 1;
    }

    
else
    
{
        
// TODO: code your application's behavior here.
        CString strHello;
        strHello.LoadString(IDS_HELLO);
        cout 
<< (LPCTSTR)strHello << endl;
    }


//////////////////////////////////////////////////////////////////////////

    HANDLE CompletionPort;
    WSADATA wsd;
    SYSTEM_INFO SystemInfo;
    SOCKADDR_IN InternetAddr;
    SOCKET Listen;

    
// 加载WinSock2.2
    WSAStartup(MAKEWORD(22), &wsd);

    
// 1.创建一个I/O完成端口
    CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
                                            NULL,
                                            
0,
                                            
0);

    
// 2.确定系统中有多少个处理器
    GetSystemInfo(&SystemInfo);

    
// 3.基于系统中可用的处理器数量创建工作器线程
    for (int i = 0; i < SystemInfo.dwNumberOfProcessors; ++i)
    
{
        HANDLE ThreadHandle;

        
// 创建一个服务器的工作器线程,并将完成端口传递到该线程
        ThreadHandle = CreateThread(NULL,
                                    
0,
                                    ServerWorkerThread,
                                    CompletionPort,
                                    
0,
                                    NULL);

        CloseHandle(ThreadHandle);
    }


    
// 4.创建一个监听套接字,以下的套路都是固定的。
    Listen = WSASocket(AF_INET,
                       SOCK_STREAM,
                       
0,
                       NULL,
                       
0,
                       WSA_FLAG_OVERLAPPED);

    InternetAddr.sin_family 
= PF_INET;
    InternetAddr.sin_port 
= htons(5000);
    InternetAddr.sin_addr.s_addr 
= htonl(INADDR_ANY);

    bind(Listen, (SOCKADDR
*)&InternetAddr, sizeof(InternetAddr));

    listen(Listen, 
5);

    BOOL b 
= TRUE;

    
while (b)
    
{
        PER_HANDLE_DATA 
* PerHandleData = NULL;
        SOCKADDR_IN saRemote;
        SOCKET Accept;
        
int RemoteLen;

        
// 5.接收连接,并分配完成端口,这儿可以用AcceptEx来代替,以创
         // 建可伸缩的Winsock应用程序。

        RemoteLen = sizeof(saRemote);
        Accept 
= accept(Listen, (SOCKADDR*)&saRemote, &RemoteLen);

        
// 6.创建用来和套接字关联的单句柄数据信息结构
        PerHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR, 
                                                       
sizeof(PER_HANDLE_DATA));

        cout 
<< "Socket number " << Accept << " connected" << endl;

        PerHandleData
->Socket = Accept;
        memcpy(
&PerHandleData->ClientAddr, &saRemote, RemoteLen);

        
// 7.将接受套接字和完成端口关联起来
        CreateIoCompletionPort((HANDLE)Accept,
                               CompletionPort,
                               (DWORD)PerHandleData,
                               
0);

        
// 开始在接受套接字上处理I/O
        
// 使用重叠I/O机制,在新建的套接字上投递一个或多个异步
         // WSARecv 或 WSASend请求。这些I/O请求完成后,工作者线程
         // 会为I/O请求提供服务,之后就可以坐享其成了

        static int const DATA_BUFSIZE = 4096; //

        DWORD RecvBytes 
= 0;
        DWORD Flags 
= 0;

        
// 单I/O操作数据
        LPPER_IO_DATA PerIoData = NULL;
        PerIoData 
= (LPPER_IO_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_DATA));
        ZeroMemory(
&(PerIoData->Overlapped), sizeof(OVERLAPPED));        

        PerIoData
->DataBuf.len = 1024;
        PerIoData
->DataBuf.buf = PerIoData->buffer;
        PerIoData
->OperationType = 0// read
        WSARecv(PerHandleData->Socket,
                
&(PerIoData->DataBuf),
                
1,
                
&RecvBytes,
                
&Flags,
                
&(PerIoData->Overlapped),
                NULL);
    }


//////////////////////////////////////////////////////////////////////////

    
return nRetCode;
}


//////////////////////////////////////////////////////////////////////////

DWORD WINAPI ServerWorkerThread(LPVOID lpParam)
{
    HANDLE CompletionPort 
= (HANDLE)lpParam;
    DWORD BytesTransferred;
    LPOVERLAPPED lpOverlapped;
    LPPER_HANDLE_DATA PerHandleData 
= NULL;
    LPPER_IO_DATA PerIoData 
= NULL;
    DWORD SendBytes;
    DWORD RecvBytes;
    DWORD Flags;
    BOOL bRet 
= FALSE;

    
while (TRUE)
    
{
        bRet 
= GetQueuedCompletionStatus(CompletionPort,
                                         
&BytesTransferred,
                                         (PULONG_PTR)
  
                                           &
PerHandleData,
                                         (LPOVERLAPPED
*)
                                           &lpOverlapped,
                                         INFINITE);

        
// 检查成功的返回,这儿要注意使用这个宏CONTAINING_RECORD
        PerIoData = (LPPER_IO_DATA)CONTAINING_RECORD(lpOverlapped, 
                                                     PER_IO_DATA, 
                                                     Overlapped);

        
// 先检查一下,看看是否在套接字上已有错误发生
        if (0 == BytesTransferred) 
        
{
            closesocket(PerHandleData
->Socket);
            GlobalFree(PerHandleData);
            GlobalFree(PerIoData);

            
continue;
        }


        
// 数据处理
        
// 成功了!!!这儿就收到了来自客户端的数据
        cout << PerIoData->DataBuf.buf << endl;

        Flags 
= 0;

        
// 为下一个重叠调用建立单I/O操作数据
        ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));

        PerIoData
->DataBuf.len = 1024;
        PerIoData
->DataBuf.buf = PerIoData->buffer;
        PerIoData
->OperationType = 0// read
        WSARecv(PerHandleData->Socket,
                
&(PerIoData->DataBuf),
                
1,
                
&RecvBytes,
                
&Flags,
                
&(PerIoData->Overlapped),
                NULL);
    }


    
return 0;
}


//////////////////////////////////////////////////////////////////////////




   当然为了测试,各种异常处理都没有写,大家不要学我哦。
                                                                     
发表于 2005-04-19 13:26 乱石铺街 阅读(8229) | 评论 (11)编辑 收藏

2005年4月15日 #

        近一个月来,论坛上发生了不少大事,牛人们纷纷告别了论坛,偶也附庸一把。不过偶的告别方式多少有点悲壮。本来我是想找个斑竹帮我封几个月的,不过没能如愿。没方法,只得退而求其次,在VC版玩起散分的游戏,一不小心成了“万人景仰”的对象,呵呵,在VC版一抬头就能看到偶的大名。不过也连累了不少好兄弟,在此向他们表示深深的歉意!屈指算来,偶在论坛上混了也差不多半年了,从坛子的高手上学到了不少东西,真是牛人遍地都是阿。当然了,有得必有失,失去的永远留在记忆中。接下来将会进入一个忙碌的夏天,也许秋天就会收获,冬天就会开始漫长的另一种生活方式......

 
发表于 2005-04-15 18:32 乱石铺街 阅读(2659) | 评论 (6)编辑 收藏

2005年4月8日 #

    前两天有个网友问这个问题,我把我的源代码都给他了,他就是调试不明白,费了我好多口舌,他还是没搞定。获取IP协议统计信息
主要有4个API函数,GetIpStatistics,GetIcmpStatistics,GetTcpStatistics,GetUdpStatistics。这些函数产生的
信息和带上-s选项执行Netstat.exe程序时返回的信息一样。看源码吧,都有详细的文字注释。
我决定把源码删掉,贴这种代码太没意思了。
发表于 2005-04-08 13:23 乱石铺街 阅读(1477) | 评论 (0)编辑 收藏

2005年3月26日 #

    大家请勿见笑,我以前使用dynamic_cast这个C++转换操作符从未成功过.我还一直纳闷那,亦不知是何原因.今天一个偶然的机会终于让我找到原因了.
    原因真是很低级阿.只要在Project->Settings中选C/C++那个Tab,然后再Project options中填入/GR即可。我很晕阿!

发表于 2005-03-26 21:40 乱石铺街 阅读(3368) | 评论 (6)编辑 收藏

2005年3月20日 #

    相传文革期间,北京有“四大不要脸”,其中之一就有郭沫若。大家看一看郭沫若写的拍斯大林马屁的诗,要多肉麻就有多肉麻。据郭沫若考证王羲之的《兰亭序》有后人伪造的嫌疑,姑且不论这些,我这次向大家介绍的是天下第二行书---唐朝颜真卿的《祭侄文稿》,这次来个链接,让大家一睹天下第二行书的风采。http://www.wenyi.com/art/shufa/suitang/32.htm 再来一个
http://www.116.com.cn/col/old/like/picture/shufa/files/109437.shtml
    

     颜真卿系行草墨迹,原迹藏台湾故宫博物院。

    《祭侄稿》全称《祭侄季明文稿》,书于唐乾元元年(公元七百五十八年)。麻纸本,行书 纵28.2厘米 横75.5厘米,二十三行,每行十一二字不等,共二百三十四字。铃有“赵氏子昴氏”、“大雅”、“鲜于”、“枢”、“鲜于枢伯几父”、“鲜于”等印。曾经宋宣和内府、元张晏、鲜于枢、明吴廷、清徐乾学、王鸿绪、清内府等收藏,现藏台北故宫博物院。
   《祭侄稿》是颜真卿为祭奠就义于安史之乱的侄子颜季明所作。 唐天宝十四年(775),安禄山谋反,平原太守颜真卿联络其从兄常山太守颜杲卿起兵讨伐叛军。次年正月,叛军史思明部攻陷常山,颜杲卿及其少子季明被捕,并先后遇害,颜氏一门被害30余口。唐肃宗乾元元年(公元七五八年),颜真卿命人到河北寻访季明的首骨携归,挥泪写下这篇留芳千古的祭文。
    元鲜于枢跋语谓:“《祭侄季明文稿》,天下行书第二、” 元陈深日:“《祭侄季明文稿》,纵笔浩放,一泻千里;时出遒劲, 杂以流丽: 或若篆籀, 或若镌刻, 其妙解处,殆若天造 岂非当时注思为文,而于字画无意于工, 而反极工耶?”
    《祭侄稿》作为颜书著名的“三稿(另二稿《争坐位稿》,《告伯父文稿》)之一,曾收入宋、明、清诸代从刻本中,历代效仿者不绝,褒赞不断。 

     《兰亭序》乃王羲之借着游兰亭的雅兴泼墨挥毫而成,《祭侄稿》的创作环境与其截然相反,颜真卿在极其悲痛的心情下一挥而就。读《祭侄稿》,我们仿佛能隐隐感觉到作者的心情。

        


发表于 2005-03-20 11:20 乱石铺街 阅读(2269) | 评论 (2)编辑 收藏

    时常在论坛上看到有人问这个VC操作Word或者Excel有没有书系统地介绍如何去做,有这个必要吗?其实捅破这层窗户纸,你就会恍然大悟,原来是这么回事啊!在此我觉得有必要把我工作中操纵Excel的一点小体会拿出来和大家共享,也许对初学者能有所帮助,高手就不要看了。操作Word请看牛人yingkou的BLOG(http://blog.vckbase.com/yingkou) .基本步骤如下

        一、Excel的层次结构   
        Application

               Workbooks

                   Workbook

                    ......

               Worksheets

                   Worksheet

                    ......

               Range

                   Font

                   Borders

                    ......

            .......


        二、插入类型库

        1、在一个已有的MFC工程按Ctrl + W 弹出ClassWizard对话框。
        2、Add Class...\From a type Library... 在 Office 目录中,找到你想使用的Excel类型库(Offce2000下,此目录在C:\Program Files\Microsoft Office\Office\EXCEL9.OLB)。选择EXCEL9.OLB此类型文件。
        3、在弹出的对话框中选择要添加的类,具体选那些类要根据实际情况而定。当然你也可以全选。

          三、基本操作

           当你要选用Excel生成报表时,表的结构可能有固定的部分,这时做一个模板,这样可以减少编码的负担。加载Excel模板的代码如下。
        

    _Application  ExcelApp;           // 定义Excel应用程序
       Workbooks          wbsBooks;
      _Workbook          wbBook;
      Worksheets         wssSheets;
      _Worksheet         wsSheet;
      Range        rngXls;
      FontXls            font;               // 字体
      BordersXls         border;         // 边框
      // 初始化Com
    if (::CoInitialize( NULL ) == E_INVALIDARG)
  
{
              AfxMessageBox(_T(
"初始化Com失败!"));
    }


    
// 创建Excel2000服务器(启动Excel)
    if ( !ExcelApp.CreateDispatch(_T("Excel.Application"), NULL))
  
{
        AfxMessageBox(_T(
"创建Excel2000服务失败!"));
        ::CoUninitialize();

    }
   
       ExcelApp.SetVisible(FALSE);  // 隐藏
       
     CString strPath;
    strPath 
+= "C:\\template.xlt"//    模板的路径    
    CFileFind filefind;
    
if!filefind.FindFile( strPath ) )
  
{
        AfxMessageBox( 
"没有找到模版文档,请其查找" );
        
        CFileDialog dlg (TRUE,
                                    NULL,                                  
                                    NULL,
                                    OFN_HIDEREADONLY
|OFN_OVERWRITEPROMPT,
                                   "模版||*.xlt||",
                                   NULL );
        
        
if (IDOK == dlg.DoModal())
     
{
            strPath 
= dlg.GetPathName(); 
        }

    }


    COleVariant vOptional( (
long)DISP_E_PARAMNOTFOUND, VT_ERROR );

    
try
  
{
        wbsBooks.AttachDispatch(ExcelApp.GetWorkbooks(), TRUE);
        wbBook.AttachDispatch(wbsBooks.Add(COleVariant(strPath)), TRUE );

        wssSheets 
= wbBook.GetWorksheets();
        wsSheet 
= wssSheets.GetItem(_variant_t("Sheet1")); // Get Sheet1
          wsSheet.SetName( "Your Sheet" );    // 改名
          // 得到全部Cells,此时,rngXls 是cells的集合
          rngXls = wsSheetAcc.GetCells();      
    }

    
catch (CException e)
  
{
        AfxMessageBox( 
"" )
    }
       
        我们知道在Excel中每个单元格可以用A1,A2,C3的形式来表示。譬如获得A1到C5之间单元格集可以这样实现,rngXls = rngXls.GetRange( COleVariant(_T(“A1“)),COleVariant(_T(“C5“)) );但是我们习惯用坐标形式如(1,1),(2,1)来表示每个单元格,在上述操作中,就没有办法用我们习惯的坐标的形式实现。它们之间如何转换那?这个用如下函数实现.
       
// Converts (row,col) indices to an Excel-style A1:C1 string in Excel
void CPrintInExcel::IndexToString( int row, int col, char* strResult )