iTimothy

君看一叶舟,出没风波里


  • 首页

  • 分类

  • 归档

  • 项目

  • 关于

怎么在一个静态Picture控件中显示JPG文件

发表于 2004-12-28 | 分类于 技术控 | | 阅读次数:
字数统计: 169 字 | 阅读时长 ≈ 1 分钟

my example: HBITMAP CPicture::LoadImageFromID(UINT nIDRes) { try { HMODULE hInst=GetModuleHandle(NULL); LPCTSTR lpRes = MAKEINTRESOURCE(nIDRes); HRSRC hRsrc = ::FindResource(hInst, lpRes, “JPG”); if (NULL == hRsrc) return FALSE;

            HGLOBAL  hGlobal  =  LoadResource(hInst,  hRsrc);
            if  (NULL  ==  hGlobal)
                        return  FALSE;

            DWORD  dwSize  =  SizeofResource(hInst,  hRsrc);
            LPVOID  lpData  =  LockResource(hGlobal);
            if  (NULL  ==  lpData)
                        return  FALSE;

            //  alloc  memory  based  on  file  size
            HGLOBAL  hJPG  =  ::GlobalAlloc(GMEM_MOVEABLE,  dwSize);
            LPVOID  lpJGP  =  ::GlobalLock(hJPG);
            memcpy(lpJGP,  lpData,  dwSize);
            ::GlobalUnlock(hJPG);

            //LPVOID  pvData  =  GlobalLock(hGlobal);
            //_ASSERTE(NULL  !=  pvData);

            //  read  file  and  store  in  global  memory

            LPSTREAM  pstm  =  NULL;
            //  create  IStream*  from  global  memory
            HRESULT  hr  =  CreateStreamOnHGlobal(hJPG,  TRUE,  &pstm;);
            _ASSERTE(SUCCEEDED(hr)  &&  pstm);

            //  Create  IPicture  from  image  file
            LPPICTURE  gpPicture;

            hr  =  ::OleLoadPicture(pstm,  dwSize,  FALSE,  IID_IPicture,  (LPVOID  *)&gpPicture;);
            _ASSERTE(SUCCEEDED(hr)  &&  gpPicture);
            pstm->Release();

            OLE_HANDLE  m_picHandle;

            gpPicture->get_Handle(&m;_picHandle);
            return  (HBITMAP)m_picHandle;
}
catch  (...)
{

}
return  NULL;

} //call CPicture pic; HBITMAP hbmp=pic.LoadImageFromID(IDR_TODAY);//IDR_TODAY is jpg id (HBITMAP)::SendMessage(::GetDlgItem(this->m_hWnd,IDC_TODAY), STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp);

关于Debug和Release之本质区别的讨论

发表于 2004-12-28 | 分类于 技术控 | | 阅读次数:
字数统计: 3k 字 | 阅读时长 ≈ 11 分钟

本文主要包含如下内容:

  1. Debug 和 Release 编译方式的本质区别
  2. 哪些情况下 Release 版会出错
  3. 怎样“调试” Release 版的程序

一、Debug 和 Release 编译方式的本质区别

Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
Debug 和 Release 的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起 Release 版错误,在此不讨论)

Debug 版本: /MDd /MLd 或 /MTd 使用 Debug runtime library(调试版本的运行时刻函数库) /Od 关闭优化开关 /D “_DEBUG” 相当于 #define _DEBUG,打开编译调试代码开关(主要针对 assert函数) /ZI 创建 Edit and continue(编辑继续)数据库,这样在调试过 程中如果修改了源代码不需重新编译 /GZ 可以帮助捕获内存错误 /Gm 打开最小化重链接开关,减少链接时间

Release 版本: /MD /ML 或 /MT 使用发布版本的运行时刻函数库 /O1 或 /O2 优化开关,使程序最小或最快 /D “NDEBUG” 关闭条件编译调试代码开关(即不编译assert函数) /GF 合并重复的字符串,并将字符串常量放到只读内存,防止 被修改

实际上,Debug 和 Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。

二、哪些情况下 Release 版会出错

有了上面的介绍,我们再来逐个对照这些选项看看 Release 版错误是怎样产生的
  1. Runtime Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的 Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。编译器提供的 Runtime Library 通常很稳定,不会造成 Release 版错误;倒是由于 Debug 的 Runtime Library 加强了对错误的检测,如堆内存分配,有时会出现 Debug 有错但 Release 正常的现象。应当指出的是,如果 Debug 有错,即使 Release 正常,程序肯定是有 Bug 的,只不过可能是 Release 版的某次运行没有表现出来而已。

  2. 优化:这是造成错误的主要原因,因为关闭优化时源程序基本上是直接翻译的,而打开优化后编译器会作出一系列假设。这类错误主要有以下几种:

    (1) 帧指针(Frame Pointer)省略(简称 FPO ):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误————但 Debug 方式下,栈的访问通过 EBP 寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release 方式下,优化会省略 EBP 栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。C++ 的强类型特性能检查出大多数这样的错误,但如果用了强制类型转换,就不行了。你可以在 Release 版本中强制加入 /Oy- 编译选项来关掉帧指针省略,以确定是否此类错误。此类错误通常有:

    ● MFC 消息响应函数书写错误。正确的应为 afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam); ON_MESSAGE 宏包含强制类型转换。防止这种错误的方法之一是重定义 ON_MESSAGE 宏,把下列代码加到 stdafx.h 中(在#include “afxwin.h”之后),函数原形错误时编译会报错 #undef ON_MESSAGE #define ON_MESSAGE(message, memberFxn) \ { message, 0, 0, 0, AfxSig_lwl, \ (AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT (AFX_MSG_CALL \ CWnd::*)(WPARAM, LPARAM) > (&memberFxn;) },

    (2) volatile 型变量:volatile 告诉编译器该变量可能被程序之外的未知方式修改(如系统、其他进程和线程)。优化程序为了使程序性能提高,常把一些变量放在寄存器中(类似于 register 关键字),而其他进程只能对该变量所在的内存进行修改,而寄存器中的值没变。如果你的程序是多线程的,或者你发现某个变量的值与预期的不符而你确信已正确的设置了,则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上 volatile 试试。

    (3) 变量优化:优化程序会根据变量的使用情况优化变量。例如,函数中有一个未被使用的变量,在 Debug 版中它有可能掩盖一个数组越界,而在 Release 版中,这个变量很可能被优化调,此时数组越界会破坏栈中有用的数据。当然,实际的情况会比这复杂得多。与此有关的错误有: ● 非法访问,包括数组越界、指针错误等。例如

    void fn(void)
    {
      int i;
      i = 1;
      int a[4];
      {
        int j;
        j = 1;
      }
      a[-1] = 1;//当然错误不会这么明显,例如下标是变量
      a[4] = 1;
    }
    

    j 虽然在数组越界时已出了作用域,但其空间并未收回,因而 i 和 j 就会掩盖越界。而 Release 版由于 i、j 并未其很大作用可能会被优化掉,从而使栈被破坏。

  1. _DEBUG 与 NDEBUG :当定义了 _DEBUG 时,assert() 函数会被编译,而 NDEBUG 时不被编译。除此之外,VC++中还有一系列断言宏。这包括:

    ANSI C 断言 void assert(int expression ); C Runtime Lib 断言 _ASSERT( booleanExpression );

    _ASSERTE( booleanExpression );
    

    MFC 断言 ASSERT( booleanExpression );

    VERIFY( booleanExpression );
    ASSERT_VALID( pObject );
    ASSERT_KINDOF( classname, pobject );
    

    ATL 断言 ATLASSERT( booleanExpression ); 此外,TRACE() 宏的编译也受 _DEBUG 控制。

所有这些断言都只在 Debug版中才被编译,而在 Release 版中被忽略。唯一的例外是 VERIFY() 。事实上,这些宏都是调用了 assert() 函数,只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码,而不只是布尔表达式(例如赋值、能改变变量值的函数调用 等),那么 Release 版都不会执行这些操作,从而造成错误。初学者很容易犯这类错误,查找的方法也很简单,因为这些宏都已在上面列出,只要利用 VC++ 的 Find in Files 功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外,有些高手可能还会加入 #ifdef _DEBUG 之类的条件编译,也要注意一下。 顺便值得一提的是 VERIFY() 宏,这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查 Windows API 的返回值。有些人可能为这个原因而滥用 VERIFY() ,事实上这是危险的,因为 VERIFY() 违反了断言的思想,不能使程序代码和调试代码完全分离,最终可能会带来很多麻烦。因此,专家们建议尽量少用这个宏。

  1. /GZ 选项:这个选项会做以下这些事

    (1) 初始化内存和变量。包括用 0xCC 初始化所有自动变量,0xCD ( Cleared Data ) 初始化堆中分配的内存(即动态分配的内存,例如 new ),0xDD ( Dead Data ) 填充已被释放的堆内存(例如 delete ),0xFD( deFencde Data ) 初始化受保护的内存(debug 版在动态分配内存的前后加入保护内存以防止越界访问),其中括号中的词是微软建议的助记词。这样做的好处是这些值都很大,作为指针是不可能的(而且 32 位系统中指针很少是奇数值,在有些系统中奇数的指针会产生运行时错误),作为数值也很少遇到,而且这些值也很容易辨认,因此这很有利于在 Debug 版中发现 Release 版才会遇到的错误。要特别注意的是,很多人认为编译器会用 0 来初始化变量,这是错误的(而且这样很不利于查找错误)。 (2) 通过函数指针调用函数时,会通过检查栈指针验证函数调用的匹配性。(防止原形不匹配) (3) 函数返回前检查栈指针,确认未被修改。(防止越界访问和原形不匹配,与第二项合在一起可大致模拟帧指针省略 FPO )

    通常 /GZ 选项会造成 Debug 版出错而 Release 版正常的现象,因为 Release 版中未初始化的变量是随机的,这有可能使指针指向一个有效地址而掩盖了非法访问。

除此之外,/Gm /GF 等选项造成错误的情况比较少,而且他们的效果显而易见,比较容易发现。

三、怎样“调试” Release 版的程序

遇到 Debug 成功但 Release 失败,显然是一件很沮丧的事,而且往往无从下手。如果你看了以上的分析,结合错误的具体表现,很快找出了错误,固然很好。但如果一时找不出,以下给出了一些在这种情况下的策略。

1. 前面已经提过,Debug 和 Release 只是一组编译选项的差别,实际上并没有什么定义能区分二者。我们可以修改 Release 版的编译选项来缩小错误范围。如上所述,可以把 Release 的选项逐个改为与之相对的 Debug 选项,如 /MD 改为 /MDd、/O1 改为 /Od,或运行时间优化改为程序大小优化。注意,一次只改一个选项,看改哪个选项时错误消失,再对应该选项相关的错误,针对性地查找。这些选项在 Project\Settings... 中都可以直接通过列表选取,通常不要手动修改。由于以上的分析已相当全面,这个方法是最有效的。

2. 在编程过程中就要时常注意测试 Release 版本,以免最后代码太多,时间又很紧。

3. 在 Debug 版中使用 /W4 警告级别,这样可以从编译器获得最大限度的错误信息,比如 if( i =0 )就会引起 /W4 警告。不要忽略这些警告,通常这是你程序中的 Bug 引起的。但有时 /W4 会带来很多冗余信息,如 未使用的函数参数 警告,而很多消息处理函数都会忽略某些参数。我们可以用
  #progma warning(disable: 4702) //禁止
  //...
  #progma warning(default: 4702) //重新允许

来暂时禁止某个警告,或使用

#progma warning(push, 3) //设置警告级别为 /W3
//...
#progma warning(pop) //重设为 /W4

来暂时改变警告级别,有时你可以只在认为可疑的那一部分代码使用 /W4。

4.你也可以像 Debug 一样调试你的 Release 版,只要加入调试符号。在 Project/Settings... 中,选中 Settings for "Win32 Release",选中 C/C++ 标签,Category 选 General,Debug Info 选 Program Database。再在 Link 标签 Project options  最后加上 "/OPT:REF" (引号不要输)。这样调试器就能使用 pdb 文件中的调试符号。但调试时你会发现断点很难设置,变量也很难找到——这些都被优化过了。不过令人庆幸的是,Call Stack 窗口仍然工作正常,即使帧指针被优化,栈信息(特别是返回地址)仍然能找到。这对定位错误很有帮助。

对话框编程技巧

发表于 2004-12-28 | 分类于 技术控 | | 阅读次数:
字数统计: 629 字 | 阅读时长 ≈ 2 分钟

一、如何往基于Dialog的程序添加菜单

[1.1] 先添加菜单(IDR_MENU1)资源,并加上需要的菜单项。 [1.2] 编辑对话框资源IDD_DLGMENUTOOLBAR_DIALOG的属性,在属性对话框中选择IDR_MENU1即可。

[1.3] 假如您不希望在对话框属性中直接设置菜单,而通过代码在程序中动态生成可以采用如下方法:

[1.3.1]在CDlgMenuToolbarDlg类声名中添加成员变量CMenu m_menu 再在CDlgMenuToolbarDlg::OnInitDialog() 中添加如下代码: //加载菜单 m_menu.LoadMenu(IDR_MENU1); //设置当前菜单 SetMenu(&m;_menu); //当你不需要菜单时可以用 SetMenu(NULL);来取消当前菜单 二、如何往基于Dialog的程序添加工具栏

[2.1] 先添加工具栏(IDR_TOOLBAR1)资源,并画好各个按钮。 [2.2] 在CDlgMenuToolbarDlg类声名中添加成员变量 CToolBar m_wndtoolbar; [2.3] 在CDlgMenuToolbarDlg::OnInitDialog() 中添加如下代码 //添加一个平面工具条 if (!m_wndtoolbar.CreateEx( this,TBSTYLE_FLAT , WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS, CRect(4,4,0,0)) || !m_wndtoolbar.LoadToolBar(IDR_TOOLBAR1) ) { TRACE0(“failed to create toolbar\n”); return FALSE; } m_wndtoolbar.ShowWindow(SW_SHOW); RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); 三、为工具栏添加工具提示

[3.1] 在CDlgMenuToolbarDlg类定义中手工添加消息映射函数的定义,如下黑体部分
virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg BOOL OnToolTipText(UINT, NMHDR pNMHDR, LRESULT pResult); DECLARE_MESSAGE_MAP()

[3.2] 在CDlgMenuToolbarDlg.cpp添加函数的实现代码 //工具栏提示 BOOL CDlgMenuToolbarDlg::OnToolTipText(UINT, NMHDR pNMHDR, LRESULT pResult) { ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);

// UNICODE消息
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
//TCHAR szFullText[512];
CString strTipText;
UINT nID = pNMHDR->idFrom;

if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
    pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
{
    // idFrom为工具条的HWND
    nID = ::GetDlgCtrlID((HWND)nID);
}

if (nID != 0) //不为分隔符
{
    strTipText.LoadString(nID);
    strTipText = strTipText.Mid(strTipText.Find('\n',0)+1);

#ifndef _UNICODE if (pNMHDR->code == TTN_NEEDTEXTA) { lstrcpyn(pTTTA->szText, strTipText, sizeof(pTTTA->szText)); } else { _mbstowcsz(pTTTW->szText, strTipText, sizeof(pTTTW->szText)); }

#else if (pNMHDR->code == TTN_NEEDTEXTA) { _wcstombsz(pTTTA->szText, strTipText,sizeof(pTTTA->szText)); } else { lstrcpyn(pTTTW->szText, strTipText, sizeof(pTTTW->szText)); }

#endif

    *pResult = 0;

    // 使工具条提示窗口在最上面
    ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,SWP_NOACTIVATE|
        SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
    return TRUE;
}
return TRUE;

}

[3.3] 在CDlgMenuToolbarDlg.cpp中添加消息映射,请看如下代码中的黑体部分 BEGIN_MESSAGE_MAP(CDlgMenuToolbarDlg, CDialog) //{AFX_MSG_MAP(CDlgMenuToolbarDlg) ON_WM_PAINT() ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipText ) //}AFX_MSG_MAP END_MESSAGE_MAP()

四、永远在最前面的对话框 void CMyDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { if (nState == WA_INACTIVE) { SetForegroundWindow(); SetWindowPos(&wndTopMost;,0,0,0,0,SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); } }

五、其它 为了使你的程序看起来更酷,还可以在CDlgMenuToolbarDlg::OnPaint()中修改代码实现Dialog 填充颜色。 CPaintDC dc(this); CRect rect; GetClientRect(rect); dc.FillSolidRect(rect, RGB(60,110,170));

VC中使用存储过程

发表于 2004-12-27 | 分类于 技术控 | | 阅读次数:
字数统计: 615 字 | 阅读时长 ≈ 3 分钟

看了很多VC数据库的书,里面很少设计到用VC和存储过程操作的资料,网上找了又找,结果还是很少,收集了一下一些代码片断,以供参考。

[arrow]代码片断1:

_variant_t _vValue; _variant_t RecordsAffected; VARIANT vtRetval; vtRetval.vt = VT_I2; _CommandPtr pCmd = NULL; _ParameterPtr pPrm = NULL; _variant_t vtEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR); _variant_t vtEmpty2(DISP_E_PARAMNOTFOUND, VT_ERROR); CString tempsql; pCmd.CreateInstance( uuidof( Command ) ); pPrm.CreateInstance( uuidof( Parameter ) ); pCmd ->ActiveConnection = pConn; pCmd ->CommandType = adCmdStoredProc; pCmd ->CommandText = _bstr_t(L”sp_addumpdevice”); pPrm = pCmd ->CreateParameter( _bstr_t(“retval”),adInteger,adParamReturnValue,sizeof(int),vtRetval); pCmd ->Parameters ->Append( pPrm ); if(strcmp(sblx,”0”)==0) { pPrm = pCmd ->CreateParameter( _bstr_t(“sblx”),adChar,adParamInput,4,”disk” ); pPrm ->Value =”disk”; } else {

pPrm = pCmd ->CreateParameter( _bstr_t("sblx"),adChar,adParamInput,4,"tape");
pPrm ->Value ="tape";

}
pCmd ->Parameters ->Append( pPrm );

  pPrm = pCmd ->CreateParameter( _bstr_t("sbmc"),adVarChar,adParamInput,20,_bstr_t(sbmc));
  pPrm ->Value =_bstr_t(sbmc);
  pCmd ->Parameters ->Append( pPrm );

 pPrm = pCmd ->CreateParameter( _bstr_t("bflj"),adVarChar,adParamInput,50,_bstr_t(bflj));
 pPrm ->Value =_bstr_t(bflj);
 pCmd ->Parameters ->Append( pPrm );
 pCmd ->Execute( &vtEmpty;, &vtEmpty2;,adExecuteNoRecords);

[arrow]代码片断2:

m_pParam =m_pCommand->CreateParameter(“id”,adInteger,adParamInput,-1,(_variant_t)”10”); //给参数设置各属性 m_pCommand->Parameters->Append(m_pParam);//加入到Command对象的参数集属性中

m_pParam1=m_pCommand->CreateParameter(“Name”,adVarChar,adParamInput,20,(_variant_t)”songwenfeng”); m_pCommand->Parameters->Append(m_pParam1);

m_pParam2=m_pCommand->CreateParameter(“sdate”,adVarChar,adParamInput,32,(_variant_t)”2004-6-8”); m_pCommand->Parameters->Append(m_pParam2);

[arrow]代码片断3:

_ParameterPtr para[3]; _CommandPtr pCmd;

pCmd.CreateInstance("ADODB.Command");
para[0].CreateInstance("ADODB.Parameter");
para[1].CreateInstance("ADODB.Parameter");
para[2].CreateInstance("ADODB.Parameter");
pCmd->ActiveConnection=m_pConn;

pCmd->CommandText="存储过程名"
para[0]=pCmd->CreateParameter("",  adBSTR,adParamInput,
            sizeof(char[50]),vVar);  //字符串型输入参数
pCmd->Parameters->Append(para[0]);
para[1]=pCmd->CreateParameter("",  adInteger,adParamInput,
                                    sizeof(int),olevariantVar);  //整型输入参数
pCmd->Parameters->Append(para[1]);
para[2]=pCmd->CreateParameter("",  adBSTR,adParamOutput,
            sizeof(char[50]),"");    //字符串型输出参数
pCmd->Parameters->Append(para[2]);
pCmd->Execute(  NULL,  NULL,  adCmdStoredProc);

[arrow]代码片断4:

使用vc++ ,sql server。 假设一个表:name sex age. 现在想求出有多少个男性,多少个女性。 如果不是用存储过程,就必须一条一条的比较。

现在想问一下:如何写这个存储过程,如何在vc中调用这个存储过程,如何取得存储过程的结果。

_CommandPtr cmmd; _ParameterPtr param; HRESULT hr = cmmd.CreateInstance(__uuidof(Command)); if(FAILED(hr)) { AfxMessageBox(“NewNetDatabase()中创建_CommandPtr对象失败”); return “创建对象失败”; } cmmd->ActiveConnection = m_pConnection;//需要使用的ADO连接 cmmd->CommandType=adCmdStoredProc; cmmd->CommandText=_bstr_t(“pkg_shenrole.AddRoleInfo”);//这个就是存储过程名称 param = cmmd->CreateParameter(“”,adBigInt, adParamInput, sizeof(long),(long)(nRoleId)); cmmd->Parameters->Append(param);

利用HTTP方式上传

发表于 2004-12-27 | 分类于 技术控 | | 阅读次数:
字数统计: 483 字 | 阅读时长 ≈ 3 分钟

#include

#include

#include

#include BOOL UseHttpSendReqEx(HINTERNET hRequest, DWORD dwPostSize,CString strLocalFile); BOOL Upload(CString bstrLocalFile,CString bstrServerIP,CString strServerPort,CString bstrRemoteFile);

#define BUFFSIZE 500

void main( int argc, char **argv ) {

if (argc < 5)
{
    printf("Usage: Bigpost  \n");
    printf(" is the local file to POST\n");
    printf(" is the server's IP to POST to\n");
    printf(" is the server's Port to POST to\n");
    printf(" is the virtual path to POST to\n");
    exit(0);
}
Upload(argv[1],argv[2],argv[3],argv[4]);

} BOOL UseHttpSendReqEx(HINTERNET hRequest, DWORD dwPostSize,CString strLocalFile) { DWORD dwRead; BYTE buffer; printf(“Local file:%s\n”,strLocalFile); FILE fLocal; if((fLocal=fopen(strLocalFile,”rb”))==NULL){ printf(“Can’t open the file:%s,maybe it doesn’t exist!\n”,strLocalFile); return false; } fseek(fLocal,0L,SEEK_END); dwRead=ftell(fLocal); rewind(fLocal); buffer=(BYTE *)malloc(dwRead); if(!buffer){ printf(“not enough memory!\n”); return false; } printf(“length of file:%d\n”,dwRead); dwRead=fread(buffer,1,dwRead,fLocal); dwPostSize=dwRead;

INTERNET_BUFFERS BufferIn;
DWORD dwBytesWritten;
BOOL bRet;
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); // Must be set or error will occur
BufferIn.Next = NULL;
BufferIn.lpcszHeader = NULL;
BufferIn.dwHeadersLength = 0;
BufferIn.dwHeadersTotal = 0;
BufferIn.lpvBuffer = NULL;
BufferIn.dwBufferLength = 0;
BufferIn.dwBufferTotal = dwPostSize; // This is the only member used other than dwStructSize
BufferIn.dwOffsetLow = 0;
BufferIn.dwOffsetHigh = 0;

if(!HttpSendRequestEx( hRequest, &BufferIn;, NULL, 0, 0))
{
    printf( "Error on HttpSendRequestEx %d\n",GetLastError() );
    return FALSE;
}
bRet=TRUE;
    if(bRet=InternetWriteFile( hRequest, buffer, dwPostSize, &dwBytesWritten;))
        printf( "\r%d bytes sent.", dwPostSize);
if(!bRet)
{
    printf( "\nError on InternetWriteFile %lu\n",GetLastError() );
    return FALSE;
}

if(!HttpEndRequest(hRequest, NULL, 0, 0))
{
    printf( "Error on HttpEndRequest %lu \n", GetLastError());
    return FALSE;
}
    fclose(fLocal);
free(buffer);
return TRUE;

}

BOOL Upload(CString strLocalFile,CString strServerIP,CString strServerPort,CString strRemoteFile){ DWORD dwPostSize=0; int intServerPort=atoi(strServerPort); HINTERNET hSession = InternetOpen( “HttpSendRequestEx”, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if(!hSession) { printf(“Failed to open session\n”); return FALSE; } HINTERNET hConnect = InternetConnect(hSession, strServerIP, intServerPort, NULL, NULL, INTERNET_SERVICE_HTTP,NULL, NULL); if (!hConnect){ printf( “Failed to connect\n” ); return FALSE; }else{ HINTERNET hRequest = HttpOpenRequest(hConnect, “PUT”, strRemoteFile, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0); if (!hRequest){ printf( “Failed to open request handle\n” ); }else{ if(UseHttpSendReqEx(hRequest, dwPostSize,strLocalFile)) { char pcBuffer[BUFFSIZE]; DWORD dwBytesRead;

            printf("\nThe following was returned by the server:\n");
            do
            {    dwBytesRead=0;
                if(InternetReadFile(hRequest, pcBuffer, BUFFSIZE-1, &dwBytesRead;))
                {
                    pcBuffer[dwBytesRead]=0x00; // Null-terminate buffer
                    printf("%s", pcBuffer);
                }
                else
                    printf("\nInternetReadFile failed");
            }while(dwBytesRead>0);
            printf("\n");
        }
        if (!InternetCloseHandle(hRequest))
            printf( "Failed to close Request handle\n" );
    }
    if(!InternetCloseHandle(hConnect))
        printf("Failed to close Connect handle\n");
}
if( InternetCloseHandle( hSession ) == FALSE ){
    printf( "Failed to close Session handle\n" );
    return FALSE;
}
printf( "\nFinished.\n" );
return TRUE;

}

获取系统有几个逻辑分区

发表于 2004-12-26 | 分类于 技术控 | | 阅读次数:
字数统计: 125 字 | 阅读时长 ≈ 1 分钟

char cr[3]; char lable[12]; for(int n=0;n<=25;n++) { CString str; str.Format(“%c:”,n+’A’); strcpy(cr,str); int dt = GetDriveType(cr); int succeed = GetVolumeInformation(cr,lable,12,NULL,NULL,NULL,NULL,0); switch(dt) { case DRIVE_UNKNOWN: { str.Format(“(%s) %s is DRIVE_UNKNOWN!”,lable,cr); break; } case DRIVE_REMOVABLE: { if(succeed) { str.Format(“(%s) %s is DRIVE_REMOVABLE!”,lable,cr); } else { str.Format(“%s is DRIVE_REMOVABLE!”,cr); } break; } case DRIVE_FIXED: { str.Format(“(%s) %s is DRIVE_FIXED!”,lable,cr); break; } case DRIVE_REMOTE: { str.Format(“(%s) %s is DRIVE_REMOTE!”,lable,cr); break; } case DRIVE_CDROM: { str.Format(“(%s) %s is DRIVE_CDROM!”,lable,cr); break; } case DRIVE_RAMDISK: { str.Format(“(%s) %s is DRIVE_RAMDISK!”,lable,cr); break; } default: { str.Empty(); break; } } if(!str.IsEmpty()) { AfxMessageBox(str); } }

得到指定文件的信息

发表于 2004-12-26 | 分类于 技术控 | | 阅读次数:
字数统计: 299 字 | 阅读时长 ≈ 1 分钟

char* szFileName = “C:\EnochShen.exe”; DWORD dwSize = GetFileVersionInfoSize(szFileName,NULL); LPVOID pBlock = malloc(dwSize); GetFileVersionInfo(szFileName,0,dwSize,pBlock);

char* pVerValue = NULL;
UINT nSize = 0;
VerQueryValue(pBlock,TEXT("\\VarFileInfo\\Translation"),
    (LPVOID*)&pVerValue;,&nSize;);

CString strSubBlock,strTranslation,strTemp;
strTemp.Format("000%x",*((unsigned short int *)pVerValue));
strTranslation = strTemp.Right(4);
strTemp.Format("000%x",*((unsigned short int *)&pVerValue;[2]));
strTranslation += strTemp.Right(4);
//080404b0为中文,040904E4为英文

//文件描述
strSubBlock.Format("\\StringFileInfo\\%s\\FileDescription",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue;,&nSize;);
strSubBlock.ReleaseBuffer();
strTemp.Format("文件描述: %s",pVerValue);
AfxMessageBox(strTemp);

//内部名称
strSubBlock.Format("\\StringFileInfo\\%s\\InternalName",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue;,&nSize;);
strSubBlock.ReleaseBuffer();
strTemp.Format("文件描述: %s",pVerValue);
AfxMessageBox(strTemp);

//合法版权
strSubBlock.Format("\\StringFileInfo\\%s\\LegalTradeMarks",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue;,&nSize;);
strSubBlock.ReleaseBuffer();
strTemp.Format("合法版权: %s",pVerValue);
AfxMessageBox(strTemp);

//原始文件名
strSubBlock.Format("\\StringFileInfo\\%s\\OriginalFileName",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue;,&nSize;);
strSubBlock.ReleaseBuffer();
strTemp.Format("原始文件名: %s",pVerValue);
AfxMessageBox(strTemp);

//产品名称
strSubBlock.Format("\\StringFileInfo\\%s\\ProductName",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue;,&nSize;);
strSubBlock.ReleaseBuffer();
strTemp.Format("产品名称: %s",pVerValue);
AfxMessageBox(strTemp);

//产品版本
strSubBlock.Format("\\StringFileInfo\\%s\\ProductVersion",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue;,&nSize;);
strSubBlock.ReleaseBuffer();
strTemp.Format("产品版本: %s",pVerValue);
AfxMessageBox(strTemp);

free(pBlock);

修改注册表开机自动启动程序

发表于 2004-12-24 | 分类于 技术控 | | 阅读次数:
字数统计: 34 字 | 阅读时长 ≈ 1 分钟

HKEY hKey; char szFileName[256]; GetModuleFileName(NULL,szFileName,256); RegOpenKey(HKEY_LOCAL_MACHINE,”SOFTWARE\Microsoft\windows\currentversion\run”,&hKey;); if(m_bAutoRun) { RegSetValueEx(hKey,”RunmeAtStartup”,0,REG_SZ,(BYTE *)szFileName,sizeof(szFileName)); } else { RegDeleteValue(hKey,”RunmeAtStartup”); } RegCloseKey(hKey);

动态加载并显示图片

发表于 2004-12-22 | 分类于 技术控 | | 阅读次数:
字数统计: 119 字 | 阅读时长 ≈ 1 分钟

HBITMAP hbitmap=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),”*.bmp”, IMAGE_BITMAP,0,0, LR_CREATEDIBSECTION|LR_LOADFROMFILE); if(hbitmap==NULL) return FALSE; CBitmap m_bitmap; m_bitmap.Attach(hbitmap); HBITMAP hbitmap; //先用上面的方法动态的装载位图,然后把图片显示到Static控件上 //获得指向静态控件的指针 CStatic pStatic=(CStatic *)GetDlgItem(IDC_SHOWBMP); //获得位图句柄 HBITMAP Bitmap; //设置静态控件的样式,使其可以使用位图,并试位标显示使居中 pStatic->ModifyStyle(0xF,SS_BITMAP|SS_CENTERIMAGE); //设置静态控件显示位图 pStatic->SetBitmap(hBitmap);

ADO如何取得数据库中表的表名

发表于 2004-12-21 | 分类于 技术控 | | 阅读次数:
字数统计: 60 字 | 阅读时长 ≈ 1 分钟

_variant_t vFieldValue; CString strFieldValue; m_pRs=m_pConnection->OpenSchema(adSchemaTables); while(VARIANT_FALSE==m_pRs->IsEOF) { strFieldValue=(char)_bstr_t(m_pRs->GetCollect(“TABLE_TYPE”)); if(!strcmp(strFieldValue.GetBuffer(0),”TABLE”)||!strcmp(strFieldValue.GetBuffer(0),”table”)) { strFieldValue.ReleaseBuffer(); strFieldValue=(char)_bstr_t(m_pRs->GetCollect(“TABLE_NAME”)); m_ctlList.AddString(strFieldValue); ///把所有的表名加到控件 } m_pRs->MoveNext(); } m_pRs->Close();

用API实现繁体简体的转换

发表于 2004-12-21 | 分类于 技术控 | | 阅读次数:
字数统计: 508 字 | 阅读时长 ≈ 2 分钟
  1. 输入Big5字符,返回Gb简体字符 //————————————————————————— //函数输入Big5字符,返回Gb简体字符 //————————————————————————— AnsiString __fastcall Big2Gb(AnsiString sBig) { char pszBig5=NULL; //Big5编码的字符 wchar_t wszUnicode=NULL; //Unicode编码的字符 char pszGbt=NULL; //Gb编码的繁体字符 char pszGbs=NULL; //Gb编码的简体字符 AnsiString sGb; //返回的字符串 int iLen=0; //需要转换的字符数

    pszBig5=sBig.c_str(); //读入需要转换的字符参数

    //计算转换的字符数 iLen=MultiByteToWideChar (950, 0, pszBig5, -1, NULL,0) ; //给wszUnicode分配内存 wszUnicode=new wchar_t[iLen+1]; //转换Big5码到Unicode码,使用了API函数MultiByteToWideChar MultiByteToWideChar (950, 0, pszBig5, -1, wszUnicode,iLen);

    //计算转换的字符数 iLen=WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, NULL,0, NULL, NULL) ; //给pszGbt分配内存 pszGbt=new char[iLen+1]; //给pszGbs分配内存 pszGbs=new char[iLen+1]; //转换Unicode码到Gb码繁体,使用API函数WideCharToMultiByte WideCharToMultiByte (936, 0, (PWSTR) wszUnicode, -1, pszGbt,iLen, NULL, NULL) ;

    //转换Gb码繁体到Gb码简体,使用API函数LCMapString LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE, pszGbt, -1, pszGbs, iLen);

    //返回Gb码简体字符 sGb=pszGbs;

    //释放内存 delete [] wszUnicode; delete [] pszGbt; delete [] pszGbs;

    return sGb; }

  2. 输入Gb字符,返回Big5字符 //————————————————————————— //函数输入Gb字符,返回Big5字符 //————————————————————————— AnsiString __fastcall Gb2Big(AnsiString sGb) { char pszGbt=NULL; //Gb编码的繁体字符 char pszGbs=NULL; //Gb编码的简体字符 wchar_t wszUnicode=NULL; //Unicode编码的字符 char pszBig5=NULL; //Big5编码的字符 AnsiString sBig5; //返回的字符串 int iLen=0; //需要转换的字符数

    pszGbs=sGb.c_str(); //读入需要转换的字符参数

    //计算转换的字符数 iLen=MultiByteToWideChar (936, 0, pszGbs, -1, NULL,0) ;

    //给pszGbt分配内存 pszGbt=new char[iLen2+1]; //转换Gb码简体到Gb码繁体,使用API函数LCMapString LCMapString(0x0804,LCMAP_TRADITIONAL_CHINESE, pszGbs, -1, pszGbt, iLen2);

    //给wszUnicode分配内存 wszUnicode=new wchar_t[iLen+1]; //转换Gb码到Unicode码,使用了API函数MultiByteToWideChar MultiByteToWideChar (936, 0, pszGbt, -1, wszUnicode,iLen);

    //计算转换的字符数 iLen=WideCharToMultiByte (950, 0, (PWSTR) wszUnicode, -1, NULL,0, NULL, NULL) ; //给pszBig5分配内存 pszBig5=new char[iLen+1]; //转换Unicode码到Big5码,使用API函数WideCharToMultiByte WideCharToMultiByte (950, 0, (PWSTR) wszUnicode, -1, pszBig5,iLen, NULL, NULL) ;

    //返回Big5码字符 sBig5=pszBig5;

    //释放内存 delete [] wszUnicode; delete [] pszGbt; delete [] pszBig5;

    return sBig5; }

动态加载位图

发表于 2004-12-20 | 分类于 技术控 | | 阅读次数:
字数统计: 548 字 | 阅读时长 ≈ 3 分钟

void CCreateRandomBMPDlg::OnBtnTest() { // TODO: Add your control notification handler code here HBITMAP hBmp;

CFileDialog dlg(TRUE, "bmp", NULL, 0, "位图文件 (*.bmp)|*.bmp||", this);

if (dlg.DoModal() != IDOK)
{
    return;
}

hBmp = (HBITMAP) LoadImage(NULL, dlg.GetPathName(), IMAGE_BITMAP, 0, 0,
                    LR_LOADFROMFILE | LR_CREATEDIBSECTION);

if (hBmp == NULL)
{
    return;
}

BITMAP bm;
PBITMAPINFO bmpInf;

if (GetObject(hBmp, sizeof(bm), &bm;) == 0)
    return ;

int nPaletteSize = 0;

if (bm.bmBitsPixel < 16)
    nPaletteSize = (int) pow(2, bm.bmBitsPixel);

bmpInf = (PBITMAPINFO) LocalAlloc(LPTR,
                        sizeof(BITMAPINFOHEADER) +
                        sizeof(RGBQUAD) * nPaletteSize);

//-----------------------------------------------
bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInf->bmiHeader.biWidth = bm.bmWidth;
bmpInf->bmiHeader.biHeight = bm.bmHeight;
bmpInf->bmiHeader.biPlanes = bm.bmPlanes;
bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel;
bmpInf->bmiHeader.biCompression = BI_RGB;
bmpInf->bmiHeader.biSizeImage = (bm.bmWidth + 7) /
    8 * bm.bmHeight * bm.bmBitsPixel;
bmpInf->bmiHeader.biXPelsPerMeter = 0;
bmpInf->bmiHeader.biYPelsPerMeter = 0;
bmpInf->bmiHeader.biClrUsed = 0;
bmpInf->bmiHeader.biClrImportant = 0;
//-----------------------------------------------

HDC hDC = ::GetWindowDC(NULL);
if (!::GetDIBits(hDC, hBmp, 0, (WORD) bm.bmHeight, NULL, bmpInf,
        DIB_RGB_COLORS))
{
    LocalFree(bmpInf);
    ::ReleaseDC(NULL, hDC);
    return ;
}

void* buf = (void*) new char[bmpInf->bmiHeader.biSizeImage];
if (buf == NULL)
{
    ::ReleaseDC(NULL, hDC);
    LocalFree(bmpInf);
    return ;
}

if (!::GetDIBits(hDC, hBmp, 0, (UINT) bm.bmHeight, buf, bmpInf,
        DIB_RGB_COLORS))
{
    ::ReleaseDC(NULL, hDC);
    delete[]buf;
    LocalFree(bmpInf);
    return ;
}

::ReleaseDC(NULL, hDC);

CString sMsg;
sMsg.Format("BitsPixel:%d,width:%d,height:%d", bm.bmBitsPixel, bm.bmWidth,
        bm.bmHeight);

AfxMessageBox(sMsg);

CClientDC dc(this);

if (bm.bmBitsPixel == 8)
{
    BYTE* pData = (BYTE*) buf;

    int nWidth = bm.bmWidth;
    while (nWidth % 4 != 0)
    {
        //Bmp每行数据都是4个字节的整数倍。
        nWidth++;
    }

    for (int i = 0; i < bm.bmHeight; i++)
    {
        for (int j = 0; j < bm.bmWidth; j++)
        {
            RGBQUAD rgbQ;
            rgbQ = bmpInf->bmiColors[pData[i * nWidth + j]];
            dc.SetPixel(j, bm.bmHeight - i,
                RGB(rgbQ.rgbRed, rgbQ.rgbGreen, rgbQ.rgbBlue));
        }
    }
}
else if (bm.bmBitsPixel == 16)
{
    BYTE* pData = (BYTE*) buf;

    int nWidth = bm.bmWidth*2;
    while (nWidth % 4 != 0)
    {
        nWidth++;
    }

    BYTE red, green, blue;

    for (int i = 0; i < bm.bmHeight; i++)
    {
        for (int j = 0; j < bm.bmWidth; j++)
        {
            blue = pData[i * nWidth + j * 2] & 0x1F;
            green = pData[i * nWidth + j * 2] >> 5;
            green |= (pData[i * nWidth + j * 2 + 1] & 0x03) << 3;
            red = (pData[i * nWidth + j * 2 + 1] >> 2) & 0x1F;

            WORD wRed = red*8;
            WORD wBlue = blue*8;
            WORD wGreen = green*8;

            red = min(255, wRed);
            blue = min(255, wBlue);
            green = min(255, wGreen);

            dc.SetPixel(j, bm.bmHeight - i, RGB(red, green, blue));
        }
    }
}
else if (bm.bmBitsPixel == 24)
{
    BYTE* pData = (BYTE*) buf;

    int nWidth = bm.bmWidth*3;
    while (nWidth % 4 != 0)
    {
        nWidth++;
    }

    for (int i = 0; i < bm.bmHeight; i++)
    {
        for (int j = 0; j < bm.bmWidth; j++)
        {
            dc.SetPixel(j, bm.bmHeight -
                i,
                RGB(pData[i * nWidth + j * 3 + 2],
                    pData[i * nWidth + j * 3 + 1],
                    pData[i * nWidth + j * 3]));
        }
    }
}
else if (bm.bmBitsPixel == 32)
{
    BYTE* pData = (BYTE*) buf;

    int nWidth = bm.bmWidth*4;

    for (int i = 0; i < bm.bmHeight; i++)
    {
        for (int j = 0; j < bm.bmWidth; j++)
        {
            dc.SetPixel(j, bm.bmHeight -
                i,
                RGB(pData[i * nWidth + j * 4 + 2],
                    pData[i * nWidth + j * 4 + 1],
                    pData[i * nWidth + j * 4]));
        }
    }
}

delete[]buf;

DeleteObject(hBmp);
LocalFree(bmpInf);

}

1…434445…47
Timothy

Timothy

Timothy的技术博客,记录技术以及生活点滴

564 日志
8 分类
1187 标签
RSS
github twitter
Links
  • ZWWoOoOo
  • 花開未央
  • 守望轩
  • 大漠说程序
  • ChengBo
  • BlueAndHack
  • 程序员小辉
  • 子痕的博客
  • WoodenRobot
  • VPS大佬
  • 毕扬博客
  • VPSDad
  • 猫爪导航
  • ss1271的奋斗
  • Kian.Li
  • YoungForest
  • Fred's Blog
  • Jacklandrin
© 2025 Timothy
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4