免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
论坛 程序设计 C/C++ memo
最近访问板块 发新帖
查看: 3629 | 回复: 7
打印 上一主题 下一主题

[其他] memo [复制链接]

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-05-07 15:43 |显示全部楼层 |倒序浏览
Basic 3D Math: Matrices
Matrices are rectangular mathematical objects which have a number of rows and columns – think of it as a two-dimensional array. Take a look at the following:Above is a 3×4 Matrix (because it has 3 rows and 4 columns) – speak: 3 by 4 Matrix. Each element of the Matrix can be indexed by using the following notation: where i is the row and j the column: because the element at the 3rd rows and 2nd column has the value 10.Matrices are used in CG to represent a various number of different things like transformations and orientations.Part 1: Multiplying Matrices (Matrix Product)Matrix multiplication is not commutative, which means that the order of operation is relevant (as opposed to the multiplication of real numbers). In order to be able to multiply two matrices they must satisfy the rule that column of the first must match the rows of the second. Take a look at the following graphic which works as a simple reminder for the rules of matrix multiplication:But what’s the purpose of multiplying matrices? In 3D Programming you do Transforming a vertex with such a operation. Stop – how can i multiply a vector (which stores a vertex position) with a matrix? Vectors can be thought as Vectors with 1 Row and 4 Columns – and because multiplying a 1×4 Matrix with a 4×4 Matrix is a valid operation this works.In the first step, lets examine how to actually do the multiplication – formally this looks like:i = row index
j = column index
p = number of columns of the first matrix (or number of rows of the second one)Because a example often says more than thousand words, take a look at the following:We have two matrices: and . Multiplication of those two is possible because the number of columns of A matches the number of rows of B – the result is a 2×2 Matrix.Let’s perform the Calculation step by step.Step 1: Write down the calculation of every index for the resulting matrix
Step 2: Do the calculations
results in:Part 2: Creating Matrices for TransformationsAs mentioned above at the beginning of this document, matrices can be used to transform vectors. Its obvious that you need corresponding matrices which represent the transformation, so they are presented below – please note that they are for OpenGL only (The “why” is discussed at the end)Identity Matrix:The Identity matrix can be seen as the “reset” state matrix. If you multiply a vector with the Identity matrix you get the original vector. You initialise new matrices to the identity.Translation Matrix:X, Y and Z represent the amount you want to translate the vector on the axis.Scaling Matrix:X,Y and Z represent the amount of scaling on the corresponding axis.Rotation Matrix:There are four rotation matrices – one about each Axis (X,Y and Z) and one for rotating about an arbitrary axe. is the roation in radians.    The matrix used to rotate about an arbitrary axis is a little bit more complicated.Assumptations: Then the matrix looks like:The Vector (x,y,z) which represents the rotation axis must be normalizedMost of the time you don’t need to create those matrices by ourself because either the math library you are using provides them or you write your own.Part 3: Order of operation and combining transformationsThe order of multiplying multiple transformation matrices is cruical. In OpenGL you get the final transformation by reading your statement from left to right. Example:R is a rotation, T a translation matrix. The Vector V is first Translated and then rotated. Take a look at the pictures below to see the difference visually:In this Picture, the vertices of the Object are first multiplied by a rotation matrix (about Z) – which rotates the local object coordinates. After that a translation matrix (move along X)  is applied, so the object moves along the rotated X axis. The order of the multiplications are:As mentioned before, we read from right to left (Take Vector V, then Rotate, then Translate)This time we first multiply with a translation matrix (translate along X) and then apply a rotation matrix:Which means: Take Vector V, then translate, then rotate.Please note that the order only applies to OpenGL. In DirectX it’s from left to right – also the matrices are a little bit different in how they look like.Part 4: Going aheadMost OpenGL based 3D Libraries and Toolkits provide easy ways of creating the matrices mentioned above (i REALLY like Richard Wright’s Math3D Library which he uses in his Book OpenGL Superbible).If you want to dig deeper into the mathematics behind 3D Graphics, i highly recommend you the following two books:

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
2 [报告]
发表于 2013-05-07 20:02 |显示全部楼层
回复 2# bruceteen


    我不想自已推导,所以做了个Memo,没想一上来就被你取笑。。
星星最近如何,转Linux了么?

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
3 [报告]
发表于 2013-05-08 12:45 |显示全部楼层
回复 7# bruceteen


    哪里深奥了。用高中的数学就能推出来吧。只是俺比较懒。。。。
现在在做一个CAD/CAM系统。各种苦B。

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
4 [报告]
发表于 2013-05-09 10:10 |显示全部楼层
  1. static void Matrix3dMultiple(double rt[4][4],double multiplicand[4][4],double multiplicate[4][4]){
  2.         double rs[4][4];
  3.        
  4.         for(int iY =0;iY<_countof(rs);iY++){
  5.                 for(int iX =0;iX<_countof(rs[0]);iX++){
  6.                         rs[iY][iX] =0.0L;
  7.                         for(int iAdd=0;iAdd <_countof(multiplicand[0]);iAdd++){
  8.                                 rs[iY][iX] +=multiplicand[iY][iAdd] *multiplicate[iAdd][iX];
  9.                         }
  10.                 }
  11.         }

  12.         memcpy(rt,rs,sizeof(rs));
  13. }// end function: Matrix3dMultiple
复制代码

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
5 [报告]
发表于 2013-05-09 14:03 |显示全部楼层
本帖最后由 folklore 于 2013-05-09 15:28 编辑
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include <vector>
  5. #include <sstream>

  6. #pragma comment(lib,"User32.lib")
  7. #pragma message("Compiling command(dll): cl.exe /EHsc /Ot /Ox /W4 /LD /DDLL "__FILE__" /link /subsystem:console")
  8. #pragma message("Compiling command(exe): cl.exe /EHsc /Ot /Ox /W4 "__FILE__" /link /subsystem:console")

  9. // -- Html Helper function
  10. static std::wstring HtmlEncode(const std::wstring& html){
  11.         std::wostringstream result;
  12.         for (std::wstring::const_iterator itCh = html.begin(); itCh !=html.end(); itCh++){
  13.                 switch(*itCh){
  14.                         case L'<':
  15.                                 result <<L"&lt;";
  16.                                 break;
  17.                         case L'>':
  18.                                 result <<L"&gt;";
  19.                                 break;
  20.                         case L'&':
  21.                                 result <<L"&amp;";
  22.                                 break;
  23.                         case L'\"':
  24.                                 result <<L"&quot;";
  25.                                 break;
  26.                         default:
  27.                                 result <<static_cast<wchar_t>(*itCh);
  28.                                 break;
  29.                 }
  30.         }
  31.         return result.str();
  32. }
  33. //static std::wstring HtmlDecode(const std::wstring& html)
  34. //{
  35. //        std::wostringstream result;
  36. //        size_t iParse =0;
  37. //        while(iParse <html.length()){
  38. //                if(html.at(iParse) !=L'&'){
  39. //                        result <<html.at(iParse++);
  40. //                }else{// enter slash staus
  41. //                        std::wostringstream enctext;
  42. //                        while(html.length() >iParse &&html.at(iParse) !=L';'){
  43. //                                enctext <<html.at(iParse++);
  44. //                        }
  45. //                        if(_wcsicmp(enctext.str().c_str(),L"&lt") ==0){
  46. //                                result <<L'<';
  47. //                        }else if(_wcsicmp(enctext.str().c_str(),L"&gt") ==0){
  48. //                                result <<L'>';
  49. //                        }else if(_wcsicmp(enctext.str().c_str(),L"&amp") ==0){
  50. //                                result <<L'&';
  51. //                        }else if(_wcsicmp(enctext.str().c_str(),L"&quot") ==0){
  52. //                                result <<L'\"';
  53. //                        }
  54. //                        if(html.length() >iParse) iParse++;        // Skip semicolon
  55. //                }
  56. //        }
  57. //        return result.str();
  58. //}// end function: HtmlDecode
  59. // -- end: Html helper functions

  60. struct IOS{
  61.         std::wstring Input;
  62.         std::vector<HWND> Output;
  63. };
  64. /// <summary>
  65. ///                Walk through all windows&subwindows that shown in current desktop, and figure out the window which be identified with special UUID prop
  66. ///        </summary>
  67. /// <see>
  68. ///                See msdn to get more info aboud this function (Relative API "EnumWindows"/"EnumChildWindows")
  69. ///        </see>
  70. static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd,_In_ LPARAM lParam){
  71.         struct IOS *pIos =(struct IOS *)lParam;

  72.         HANDLE hData =::GetPropW(hwnd,pIos->Input.c_str());
  73.         if(hData !=NULL){
  74.                 pIos->Output.push_back(hwnd);
  75.                 EnumChildWindows(hwnd,EnumWindowsProc,lParam);
  76.         }
  77.         return TRUE;
  78. }// end function: EnumWindowsProc

  79. // -- local helper function
  80. static std::wstring _Makeparams(const wchar_t *const pParams){
  81.         std::wstring rsMsg;
  82.         rsMsg.append(L"\t\t\t<Params>\n");
  83.         const wchar_t *pParam =pParams;
  84.         do{
  85.                 rsMsg.append(L"\t\t\t\t<Param>");
  86.                 rsMsg.append(HtmlEncode(pParam));
  87.                 rsMsg.append(L"</Param>\n");
  88.                 while(pParam[0] !=NULL){
  89.                         pParam++;
  90.                 }// end if
  91.                 pParam++;
  92.         }while(pParam[0] !=NULL);
  93.         rsMsg.append(L"\t\t\t</Params>\n");
  94.         return rsMsg;
  95. }
  96. /// <summary>
  97. ///                MakeMessage: Input the message and translate it to XML format
  98. /// </summary>
  99. // The result string looks like
  100. // <messages>
  101. //        <message ext-code="3">
  102. //                <Title code="35" Description="">
  103. //                        <Params>
  104. //                                <Param>p1 of content<Param>
  105. //                        <Params>
  106. //                </Title>
  107. //                <Content code="53" Description="">
  108. //                        <Params>
  109. //                                <Param>p1 of content</Param>
  110. //                        <Params>
  111. //                </Content>
  112. //        </message>
  113. // </messages>
  114. static std::wstring MakeMessage(const wchar_t *const id,const long cdTitle,const wchar_t *const pTitle,const long cdBody,const wchar_t *const pBody,const wchar_t *const paramsTitle=NULL,const wchar_t *const paramsContent=NULL,const long cdExtend=-1){
  115.         (void) id;
  116.         wchar_t intbuf[MAX_PATH];        // Global buffer

  117.         // -- Xml header
  118.         std::wstring rsMsg(L"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
  119.         rsMsg.append(L"<Messages>\n");
  120.         rsMsg.append(L"\t<Message ext-code=\"");
  121.         _itow_s(cdExtend,intbuf,MAX_PATH,10);
  122.         rsMsg.append(intbuf);
  123.         rsMsg.append(L"\"");
  124.         // -- UUID if specified
  125.         if(id !=NULL){
  126.                 rsMsg.append(L" UUID=\"");rsMsg.append(HtmlEncode(id));rsMsg.append(L"\"");
  127.         }//end if
  128.         rsMsg.append(L">\n");
  129.         // -- Title
  130.         _itow_s(cdTitle,intbuf,MAX_PATH,10);
  131.         rsMsg.append(L"\t\t<Title code=\"");rsMsg.append(intbuf);rsMsg.append(L"\"");
  132.         if(pTitle !=NULL){
  133.                 rsMsg.append(L" Description=\"");rsMsg.append(HtmlEncode(pTitle));rsMsg.append(L"\"");       
  134.         }

  135.         if(paramsTitle !=NULL){
  136.                 rsMsg.append(L">\n");
  137.                 rsMsg.append(_Makeparams(paramsTitle).c_str());
  138.                 rsMsg.append(L"\t\t</Title>\n");
  139.         }else{
  140.                 rsMsg.append(L"/>\n");
  141.         }

  142.         // -- Content
  143.         _itow_s(cdBody,intbuf,MAX_PATH,10);
  144.         rsMsg.append(L"\t\t<Content code=\"");rsMsg.append(intbuf);rsMsg.append(L"\"");
  145.         if(pBody !=NULL){
  146.                 rsMsg.append(L" Description=\"");rsMsg.append(HtmlEncode(pBody));rsMsg.append(L"\"");
  147.         }
  148.         if(paramsContent !=NULL){
  149.                 rsMsg.append(L">\n");
  150.                 rsMsg.append(_Makeparams(paramsContent).c_str());
  151.                 rsMsg.append(L"\t\t</Content>\n");
  152.         }else{
  153.                 rsMsg.append(L"/>\n");
  154.         }

  155.         rsMsg.append(L"\t</Message>\n");
  156.         rsMsg.append(L"</Messages>");
  157.         return rsMsg;
  158. }// end function: MakeMessage

  159. /// <summary>
  160. ///                Send message to UI (typically main window) program that registered. The COM component can be executed in remote host.
  161. ///                This function try to send message to *local host* (and typically the local host show a message depend on the message-code).
  162. /// </summary>
  163. /// <param name="pUUIDDes">UUID of target window (via get/setprop)</param>
  164. /// <param name="id">The message id, can be null</param>
  165. /// <param name="cdTitle">Code of message title</param>
  166. /// <param name="pTitle">Message title, can be null</param>
  167. /// <param name="cdBody">Code of message body</param>
  168. /// <param name="pBody">Message content, can be null</param>
  169. /// <Return> The number of the target window </Return>
  170. extern "C" __declspec(dllexport) int SendUIMessage(const wchar_t *const pUUIDDes,wchar_t *const id,const long cdTitle,const wchar_t *const pTitle,const long cdBody,const wchar_t *const pBody,const wchar_t *const paramsTitle=NULL,const wchar_t *const paramsContent=NULL,const long cdExtend=0){
  171.         int nSent =0;
  172.         if(pUUIDDes !=NULL){
  173.                 struct IOS ios;
  174.                 ios.Input =pUUIDDes;

  175.                 ::EnumWindows(EnumWindowsProc,(LPARAM)&ios);
  176.                 for(std::vector<HWND>::iterator itHwnd =ios.Output.begin(); itHwnd !=ios.Output.end();itHwnd++){
  177.                         std::wstring msgstr =MakeMessage(id,cdTitle,pTitle,cdBody,pBody,paramsTitle,paramsContent,cdExtend);
  178.                         COPYDATASTRUCT msg ={
  179.                                 NULL,(msgstr.size()+1)<<1,(LPVOID)msgstr.c_str()
  180.                         };
  181.                         ::SendMessage(*itHwnd,WM_COPYDATA,NULL,(LPARAM)&msg);
  182.                         //MessageBoxW(*itHwnd,L"OK",L"OK",MB_OK);        // -- Try to show message at destinate window
  183.                         nSent++;
  184.                 }
  185.         }// end if
  186.         return nSent;
  187. }

  188. #if !defined(DLL)
  189. static const wchar_t *const UUIDBendCAM =L"{3B0C708E-8014-4f33-BFC8-4AE1E8F3901C}";
  190. static size_t dntwcslen(const wchar_t *const pSrc){        //double null terminal string
  191.         size_t rsSize =0;
  192.         if(pSrc !=NULL){
  193.                 do{
  194.                         while(pSrc[rsSize] !=NULL){rsSize++;}
  195.                         rsSize++;
  196.                 }while(pSrc[rsSize] !=NULL);
  197.         }
  198.         return rsSize;
  199. }
  200. int main(void){
  201.         const wchar_t *const pParams =L"Param<01>\0Param02\0";
  202.         std::wstring params;
  203.         params.resize(dntwcslen(pParams));
  204.         for(size_t iAssign =0;iAssign <params.size();iAssign++){        // the size is not include the last terminal tocken
  205.                 params.at(iAssign) =pParams[iAssign];
  206.                 //wprintf(L"%c",params.at(iAssign));
  207.         }
  208.         //wprintf(L"\n%d",dntwcslen(pParams));
  209.         if(0 ==SendUIMessage(UUIDBendCAM,NULL,123,L"Title&b",456,L"Context: <happy new year.>",params.data(),params.data())){
  210.                 std::wstring msg=MakeMessage(NULL,123,L"Title&b",456,L"Context: <happy new year.>",params.data()/*,params.data()*/);
  211.                 wprintf(L"%s",msg.c_str());
  212.         }
  213.         return 0;
  214. }
  215. #endif //!defined(DLL)
复制代码
new version

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
6 [报告]
发表于 2013-05-09 21:20 |显示全部楼层
回复 10# linux_c_py_php


    以前一直以为程序和数学是不分家的。直到有一天,有个电信公司叫我写无聊的电信业务系统。

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
7 [报告]
发表于 2013-06-28 16:17 |显示全部楼层
The following issue explain you how to apply the metries to an 3d vertex.

In order to apply a general 4x4 transformation matrix to a vertex represented as a 3 dimensional vector, you need to:
1.Expand the vector into the 4th dimension by adding a 1 as the W component:
        (x, y, z) => (x, y, z, 1)
2.Multiply the transformation matrix by the 4 dimensional vector above. The result will be another 4 dimensional vector:
        ( 4x4 matrix ) * (x, y, z, 1) => (tx, ty, tz, w)
The general formula for multiplying a 4x4 matrix by a 4x1 vector is (if I didn't mess up):
        [ m11 m12 m13 m14 ][ x ]   [ m11 * x + m12 * y + m13 * z + m14 * w ]
        [ m21 m22 m23 m24 ][ y ]   [ m21 * x + m22 * y + m23 * z + m24 * w ]
        [ m31 m32 m33 m34 ][ z ] = [ m31 * x + m32 * y + m33 * z + m34 * w ]
        [ m41 m42 m43 m44 ][ w ]   [ m41 * x + m42 * y + m43 * z + m44 * w ]
Or if you consider the usual configuration of a transformation matrix:
        [ m11 m12 m13 px ][ x ]   [ m11 * x + m12 * y + m13 * z + px ]
        [ m21 m22 m23 py ][ y ]   [ m21 * x + m22 * y + m23 * z + py ]
        [ m31 m32 m33 pz ][ z ] = [ m31 * x + m32 * y + m33 * z + pz ]
        [ 0   0   0   1  ][ 1 ]   [ 1 ]
3.Convert it back into the 3rd dimension by homogenizing the vector, i.e. dividing everything by the fourth component w:
        (tx, ty, tz, w) => (tx/w, tx/w, tz/w)

The thing is that if your transformation matrix only does a simple translation / rotation / scale, the value of w will be 1 and you can just drop the fourth component since that will be the same as dividing by 1.
But it's good to remember that it does not work for every case, e.g. with projection matrices you must remember to do this third step.

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
8 [报告]
发表于 2013-07-12 09:07 |显示全部楼层
本帖最后由 folklore 于 2013-07-12 09:08 编辑

XSL文件真蛋疼, 麻烦死了, 写个函数:

  1. ///<summary>
  2. ///  Indent format file
  3. ///</summary>
  4. ///<param name ="pXmlDoc">Source xml document object</param>
  5. ///<return>formated xml document object</return>
  6. static MSXML2::IXMLDOMDocumentPtr ApplyXmlIndent(MSXML2::IXMLDOMDocumentPtr pXmlDoc){
  7.         static const wchar_t *const XmlStyleSpecString =
  8.                 L"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
  9.                 L"<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
  10.                 L"        <xsl:output method=\"xml\" indent=\"yes\"/>\n"
  11.                 L"        <xsl:template match=\"@* | node()\">\n"
  12.                 L"                <xsl:choose>\n"
  13.                 L"                        <xsl:when test=\"not(node()) and not(text())\">\n"
  14.                 L"                                <xsl:copy>\n"
  15.                 L"                                        <xsl:apply-templates select=\"@*\"/>\n"
  16.                 L"                                </xsl:copy>\n"
  17.                 L"                        </xsl:when>\n"
  18.                 L"                        <xsl:otherwise>\n"
  19.                 L"                                <xsl:copy>\n"
  20.                 L"                                        <xsl:apply-templates select=\"@* | node()\"/>\n"
  21.                 L"                                </xsl:copy>\n"
  22.                 L"                        </xsl:otherwise>\n"
  23.                 L"                </xsl:choose>\n"
  24.                 L"        </xsl:template>\n"
  25.                 L"</xsl:stylesheet>";

  26.         //Create the final document which will be indented properly
  27.         MSXML2::IXMLDOMDocumentPtr pXMLFormattedDoc(__uuidof(MSXML2::DOMDocument)),fmtXml(__uuidof(MSXML2::DOMDocument));

  28.         do{
  29.                 if(fmtXml->loadXML(_bstr_t(XmlStyleSpecString)) ==VARIANT_FALSE){
  30.                         break;
  31.                 }

  32.                 IDispatchPtr pDispatch;
  33.                 HRESULT hr = pXMLFormattedDoc->QueryInterface(IID_IDispatch, (void**)&pDispatch);
  34.                 if(FAILED(hr)){
  35.                         break;
  36.                 }

  37.                 _variant_t        vtOutObject;
  38.                 vtOutObject.vt = VT_DISPATCH;
  39.                 vtOutObject.pdispVal = pDispatch;
  40.                 vtOutObject.pdispVal->AddRef();        //< required

  41.                 //Apply the transformation to format the final document       
  42.                 pXmlDoc->transformNodeToObject(fmtXml,vtOutObject);

  43.                 //The default encoding method is utf-16. Change it to utf-8
  44.                 MSXML2::IXMLDOMNodePtr pXMLFirstChild = pXMLFormattedDoc->GetfirstChild();                                // <?xml version="1.0" encoding="UTF-8"?>
  45.                 MSXML2::IXMLDOMNamedNodeMapPtr pXMLAttributeMap =  pXMLFirstChild->Getattributes();                // A map of the a attributes (vesrsion, encoding) values (1.0, utf-8) pair
  46.                 MSXML2::IXMLDOMNodePtr pXMLEncodNode = pXMLAttributeMap->getNamedItem(_bstr_t(L"encoding"));       
  47.                 pXMLEncodNode->PutnodeValue(_bstr_t(L"utf-8"));//encoding = UTF-8       

  48.         }while(false);
  49.         return pXMLFormattedDoc;
  50. }//end function: ApplyXmlIndent
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP