GSI

기존의 스크롤뷰가 페이지의 크기가 커지면, 많은 문제점이 생기게 됩니다.
좀 불합리성이 보이네욤..
더블 버퍼링도 좀 부피가 커져서 효율이 떨어 지고. 스크롤의 최대 값도 좀 걸리고.
그래서 싱글 뷰에 직접 컨트롤 박아서 처리해봤어요.

사용자 삽입 이미지
위에서 보는 거 처름 CView 에 View, ScrollBar등을 달아서
움직이도록 처리 해봤습니다.

더 보정할건 많지만. 기초 프로토타입으로는 좋은거 같네요..

앞으로 여기에 마우스로 컨트롤 추가 하고 타임 라인 비슷한 화면을 구성해 볼려고 합니다.
잘 되면 좋겠네요 ^^.

관련코드 :
Posted by gsi
:

XML 처리방법

C++ 2007. 12. 6. 12:53 |

XML 데이터 처리 하는 방법 정리.
파일 읽기, http 정보 읽기, 노드 정보 출력, 노드 검색 정보 출력


1. XML 파일 읽어서 출력하기

MSXML2::IXMLDOMDocument2Ptr pDoc; // XML Document 선언
pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument)); // 인스턴스 생성

HRESULT hr = pDoc->load((_variant_t)".\\test.xml");
if(hr == 0) {
 AfxMessageBox("로딩 에러");
 return;
}
AfxMessageBox(pDoc->xml);

2. http을 통한 XML 파일 읽어서 출력하기

MSXML2::IXMLDOMDocument2Ptr pDoc; // XML Document 선언
pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument)); // 인스턴스 생성

DWORD startTick = GetTickCount();
pDoc->put_async(VARIANT_FALSE);
HRESULT hr = pDoc->load((_variant_t)"http://localhost/TestXml/test2.xml");
if(hr == 0) {
 AfxMessageBox("로딩 에러");
 return;
}
AfxMessageBox(pDoc->xml);

3. XML 데이터의 첫번째 해당 노드값 읽어서 출력하기

MSXML2::IXMLDOMDocument2Ptr pDoc; // XML Document 선언
pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument)); // 인스턴스 생성

HRESULT hr = pDoc->load((_variant_t)".\\test.xml");
if(hr == 0) {
 AfxMessageBox("로딩 에러");
 return;
}

MSXML2::IXMLDOMNodePtr pNode;
pNode = pDoc->selectSingleNode(L"//name");

CString outString;
outString.Format("[검색결과] 노드명:%s, 노드값:%s\r\n", (LPCTSTR)pNode->GetnodeName(), (LPCTSTR)pNode->Gettext());
AfxMessageBox(outString);

4. XML 데이터의 해당 노드값 모두 읽어서 출력하기

MSXML2::IXMLDOMDocument2Ptr pDoc; // XML Document 선언
pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument)); // 인스턴스 생성

HRESULT hr = pDoc->load((_variant_t)".\\test.xml");
if(hr == 0) {
 AfxMessageBox("로딩 에러");
 return;
}

MSXML2::IXMLDOMNodeListPtr pNodeList;
pNodeList = pDoc->selectNodes(L"//name");

CString outTotalString;
for(int i = 0; i < pNodeList->length; i++) {
 CString outString;
 outString.Format("[검색결과] 노드명:%s, 노드값:%s\r\n",
  (LPCTSTR)pNodeList->Getitem(i)->GetnodeName(),
  (LPCTSTR)pNodeList->Getitem(i)->Gettext());
 outTotalString.Append(outString);
}
AfxMessageBox(outTotalString);

나머지 노드값 변경하는 방법,
속성값 읽어 오기 및 변경 방법 등을 정리 해야 함.

테스트 소스 :

Posted by gsi
:

설정방법 :
1. MSXML 4.0을 설치한다.

2. VC++ 디렉토리  설정부분에서 include, lib를 설정해 준다.

3. MFC Dialog로 프로젝트 생성시 "자동화" 를 체크 해준다.
   3.1. 아마도 이런 코드가 더 추가되는거 같다. 다른 코드가 더 있는지는 잘 모르겠다.
// 이 매크로는 COleObjectFactory 생성자에 대한 bMultiInstance 매개 변수에 TRUE를
// 전달하는 점만 제외하면 IMPLEMENT_OLECREATE와 같습니다.
// 자동화 컨트롤러에서 요청한 각 자동화 프록시 개체에 대해 이 응용 프로그램에 대한 별도의 인스턴스가 시작되도록 합니다.
#ifndef IMPLEMENT_OLECREATE2
#define IMPLEMENT_OLECREATE2(class_name, external_name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
 AFX_DATADEF COleObjectFactory class_name::factory(class_name::guid, \
  RUNTIME_CLASS(class_name), TRUE, _T(external_name)); \
 const AFX_DATADEF GUID class_name::guid = \
  { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } };
#endif // IMPLEMENT_OLECREATE2

4. stdafx.h 파일에 아래의 코드를 추가한다.
#import <msxml4.dll>
using namespace MSXML2;

5. 테스트로 OK 버튼에 아래와 같은 내용을 추가 해서 테스트를 진행한다.
void CReadXML2Dlg::OnBnClickedOk()
{
 MSXML2::IXMLDOMDocument2Ptr pDoc; // XML Document 선언
 MSXML2::IXMLDOMProcessingInstructionPtr pPI; // XML ProcessingInstruction 선언
 MSXML2::IXMLDOMElementPtr pRootElement; // XML Element 선언
 MSXML2::IXMLDOMElementPtr pElement;
 MSXML2::IXMLDOMTextPtr pText; // XML Text 선언
 pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument)); // 인스턴스 생성
 pPI=pDoc->createProcessingInstruction(L"xml",L"version=\"1.0\" encoding=\"euc-kr\""); // PI 생성
 pRootElement=pDoc->createElement(L"IRC"); // Root element 생성
 pElement=pDoc->createElement(L"Nick"); // "Nick" element 생성
 pText=pDoc->createTextNode(L"wiluby"); // "wiluby" text element 생성
 pDoc->appendChild(pPI); // ProcessingIsntruction 추가
 pElement->appendChild(pText); // text element를 "Nick" element에 추가
 pRootElement->appendChild(pElement); // "Nick" element를 root element에 추가
 pDoc->appendChild(pRootElement); // Root element를 문서에 추가
 AfxMessageBox(pDoc->xml); // XML 내용을 보자!!
 //
 OnOK();
}

그럼 아래와 같은 내용의 대화 상자가 나오게 된다.

사용자 삽입 이미지

그리고 제 환경이 그러서인지는 모르겠다. 2008을 깔고, .net 3.5를 다 깐 상태라서 MSXML 6.0이라는 폴더가 만들어져 있는 상태이다.

그래서 위의 코드 처름 스마트 포인터 형태의 IXMLDOMProcessingInstructionPtr  이런 변수들을 그냥 사용하면 아래와 같은 내용의 에러가 나오게 된다.

d:\temp\ReadXML2\ReadXML2\ReadXML2Dlg.cpp(205) : error C2872: 'IXMLDOMProcessingInstructionPtr' : 모호한 기호입니다.
        'c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\comdefsp.h(1261) : _com_ptr_t<_IIID> IXMLDOMProcessingInstructionPtr'일 수 있습니다.
        with
        [
            _IIID=_com_IIID<IXMLDOMProcessingInstruction,& _GUID_2933bf89_7b36_11d2_b20e_00c04f983e60>
        ]
        또는       'd:\temp\ReadXML2\ReadXML2\Debug\msxml4.tlh(298) : MSXML2::IXMLDOMProcessingInstructionPtr'일 수 있습니다.

아무래도 네임 스페이스 쪽의 충돌인지 선언이 안되어서 그런지는 잘 모르겠다.
하지만 위의 코드 처름 MSXML2:: 를 붙여 주면 해결이 된다.

이상.
 

Posted by gsi
:

MSXML 설치파일

C++ 2007. 12. 6. 09:18 |

xml을 읽기 위해서 필요한 데이터 파일

설치파일 :


Posted by gsi
:

DataGridView dgv = ...
dgv 라고 객체를 생성 했다고 햇을때.

DataSet에서 값을 가져 오고,
현재 Row를 선택 했을때 SelectedIndex 같은 프로퍼티가 제공되지 않는거 같아요.
그래서 현재 구현한 방법은 아래와 같습니다.

자세한 코드 내용은 저도 잘 모르겠네요.
혹시 아시면 코멘트 부탁 드려요.

DataGridView dgv = sender as DataGridView;
//MessageBox.Show("선택한 Row=" + dgv.SelectedCells[0].RowIndex.ToString());

DataTable dtItem = azitro_testDataSet.Tables[0];
DataRow rwItem = dtItem.Rows[dgv.SelectedCells[0].RowIndex];


이상.
Posted by gsi
:

DataSet을 생성하고 그곳에 있는 특정 Row의 값을 가져 와서
Row 내부에 있는 Column의 정보를 가져 올때 아래와 같이 하면 됨.

DataTable dtItem = azitro_testDataSet.Tables[0];  // DataSet에서 DataTable을 가져옴
DataRow rwItem = dtItem.Rows[0];  // DataTable에서 DataRow을 가져옴.

string strCatenum = rwItem["cate_Num"].ToString(); // DataRow의 해당 컬럼 정보를 가져옴.

Posted by gsi
:

[C#] Graphics 객체 사용하기

C# 2007. 12. 5. 12:30 |

Graphics objGraphics = null;
objGraphics = this.CreateGraphics();
objGraphics.Clear(SystemColors.Control);
objGraphics.DrawRectangle(Pens.Blue,
    picShowPicture.Left - 1, picShowPicture.Top - 1,
    picShowPicture.Width + 1, picShowPicture.Height + 1);
objGraphics.Dispose();

> 사각형 테두리를 그린다.
Posted by gsi
:

[C#] Picture Viewer

C# 2007. 12. 5. 10:58 |

사용자 삽입 이미지
1. PictureBox를 추가 한다.
2. Select Picture 버튼을 추가 한다.
3. Quit 버튼을 추가한다.
4. OpenFileDialog 파일 오픈 상자를 위한 컨트롤을 추가 한다.

소스 코드 :

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnSelectPicture_Click(object sender, EventArgs e)
        {
            if (ofdSelectPicture.ShowDialog() == DialogResult.OK)
            {
                picShowPicture.Image = Image.FromFile(ofdSelectPicture.FileName);
                this.Text = string.Concat("Picture Viewer(" + ofdSelectPicture.FileName + ")");
            }
        }

        private void btnQuit_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }

Posted by gsi
:

DB Viewer Sample1

DB&XML 2007. 12. 4. 20:50 |

사용자 삽입 이미지

ComboBox의 내용을 토대로 해서 "업데이트" 버튼을 누르면 DataGridView에 내용을 업데이트 하는 샘플 입니다.
원래 콤보 박스의 내용을 xml이나 Collection의 객체를 사용해서 연동할려고 했지만.
역시 -.- 안되더군요. (잘몰라서, 아시는분 꼭 연락 주세요 ^^)
그래서 아래와 같이 아이템은 입력 했습니다.

사용자 삽입 이미지

"업데이트" 버튼 이벤트는 아래와 같이 처리 하였습니다.
 ComboBox의 selectedIndex의 값을 사용해서 DB의 테이블 내용과 같게 switch 로 변환해 주었습니다. (원래 이걸.. ComboBox의 DisplayMember, ValueMember를 사용할려고 했는데, ^^)

        enum enItemType { IT_C, IT_B, IT_R, IT_S };

        private string GetItemType(enItemType it)
        {
            switch (it)
            {
                case enItemType.IT_C:
                    return "C";
                case enItemType.IT_B:
                    return "B";
                case enItemType.IT_R:
                    return "R";
                case enItemType.IT_S:
                    return "S";
            }
            return "";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            enItemType curit = (enItemType)comboBox1.SelectedIndex;
            string selvalue = GetItemType(curit);

            this.itemTableAdapter.FilterItemTypeToFill(this.testDataSet.item, selvalue);
        }

string selvalue = GetItemType(curit);

이 코드를 통해서 selvalue에 나오는 값은 해당 테이블의 값이 생성되게 된다.

이걸 사용해서... 쿼리 문에 입력해 줍니다.
 this.itemTableAdapter.FilterItemTypeToFill(this.testDataSet.item, selvalue);

[참고]

Query Builder 내용은 아래와 같이 하면 됩니다.
SELECT   item_code, item_detail, buy_select,
FROM      item
WHERE   (cate_Num = @catenum)   <-- 이걸로 처리 해야 입력하는 값에 따른 리스트가 나옴.
Posted by gsi
:

사용자 삽입 이미지

기존에는 mfc를 사용해서 확장성 있는 컨트롤 만드는게 개념이 너무 안잡혔다.
지금 생각해 보면 너무 몰랐던 것이다.

하지만 지금은 wpf 및 기타 다른 기술들을 배우다 보면서,
확장성에 대해서 많이 발전한 모습이 눈에 뛰는거 같다.

아래의 에제는 ActiveX 폼에
CStatic로 타이틀 바를 만들고 그 아래에 이미지 박스를 CStatic로 추가 해서
컨트롤을 하나 만들려고 한다.

임시로 만들어 놓은 작업 물이지만 참고 하기에 좋을거 같아서.
우선 추가를 해놓을려고 한다.

혹시 궁금하시면 질문 주세요.

관련코드 :

Posted by gsi
:

CXImage 연동 라이브러리.

C++ 2007. 12. 3. 18:09 |

CxImage 라이브러리 폴더를 해당 프로젝트에 추가 한다.

1. 인클루드를 추가한다.

#include "./CXImage599_Lib/ximage.h"
#pragma comment(lib, "./CXImage599_Lib/cximaged.lib")

2. 해당 경로명의 확장자(이미지 타입)을 얻어 오는 함수를 추가한다.

// CDlgSequencePage 메시지 처리기입니다.
int GetTypeFromFileName(CString& str)
{
 CString fileName = str;
 CString ext3=fileName.Right(3);
 CString ext4=fileName.Right(4);
#if CXIMAGE_SUPPORT_PNG
 if(ext3.CompareNoCase(_T("png"))==0)
  return CXIMAGE_FORMAT_PNG;
#endif
#if CXIMAGE_SUPPORT_BMP
 else if(ext3.CompareNoCase(_T("bmp"))==0)
  return CXIMAGE_SUPPORT_BMP;
#endif
#if CXIMAGE_SUPPORT_JPG
 else if(ext3.CompareNoCase(_T("jpg"))==0)
  return CXIMAGE_SUPPORT_JPG;
#endif

 return CXIMAGE_FORMAT_UNKNOWN;
}

3. 이미지 읽어 오는 함수를 추가한다.

CxImage* CDlgProgrammingPage::GetImage(CString& strPath)
{
 int nImageType=GetTypeFromFileName(strPath);
 if(nImageType==CXIMAGE_FORMAT_UNKNOWN) {
  MessageBox("해당 파일을 읽을 수 없습니다.", "에러", MB_OK);
  return NULL;
 }

 CxImage* pImg = new CxImage(strPath, nImageType);

 if(pImg->IsValid() == false) {
  delete pImg;

  MessageBox("해당 파일을 읽을 수 없습니다.", "에러", MB_OK);
  return NULL;
 }

 return pImg;
}

관련 라이브러리 :

Posted by gsi
:

    public partial class UserControl1 : UserControl
    {
        public static DependencyProperty InputTextProperty;

        public UserControl1()
        {
            InitializeComponent();
       
            //
            InputTextProperty = DependencyProperty.Register("InputText", typeof(string),
                            typeof(UserControl1),
                            new FrameworkPropertyMetadata("none", new PropertyChangedCallback(OnInputTextChanged)));
        }

        public string InputText
        {
            set { SetValue(InputTextProperty, value); }
            get { return (string)GetValue(InputTextProperty); }
        }
         
        private void OnInputTextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            TextBlock tb = this.FindName("txtShow") as TextBlock;

            tb.Text = InputText;
        }
    }

관련코드 :

Posted by gsi
:

컨트롤의 특정 부분을 사용해서 타이틀바로 인식하게 하고 싶을때가 있습니다.
그럴때는 아래와 같은 코드를 사용하면 됩니다.

void CDlgTest01::OnLButtonDown(UINT nFlags, CPoint point)
{
 CDialog::OnLButtonDown(nFlags, point);
 TRACE2("mousepos : %d, %d\n", point.x, point.y);
 PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKEWPARAM(point.x, point.y));
}

이거 말고 Static 컨트롤을 사용해서 클릭 이벤트를 추가 하고 캡션 처리는 아래와 같이 하면 되는거 같네요.

우선 Dialog에 Static 컨트롤을 추가 하고 그 컨트롤을 사용해서 처리 해줄때
Static의 "IDC_STATIC_CAPTION" 이벤트 함수를 추가 했습니다.
하지만 해보면 이 이벤트 함수는 호출이 되지 않는데요.
왜냐 하면 스타일에 "SS_NOTIFY"가 없어서 그렇습니다.

BOOL CDlgTest01::OnInitDialog() 함수 안에 아래의 코드를 추가 합니다.

GetDlgItem(IDC_STATIC_CAPTION)->ModifyStyle(0, SS_NOTIFY);

이제 디버깅을 해보시면 호출이 되는걸 확인할 수 있습니다.

마지막으로 작업해 주어야 하는 부분이
마우스 위치를 얻어와서 PostMessage를 호출해 주면 됩니다.

void CDlgTest01::OnStnClickedStaticCaption()
{
 CPoint mousePos;
 GetCursorPos(&mousePos);
 ScreenToClient(&mousePos);
 //TRACE2("Edit mousepos : %d, %d\n", mousePos.x, mousePos.y);

 PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKEWPARAM(mousePos.x, mousePos.y));
}

Posted by gsi
:

사용자 삽입 이미지


슬라이더 형태의 특정한 수치 정보를 담고 있다.
마우스로 바의 내부를 클릭 하면 해당 위치까지 녹색의 바가 에니메이션 플레이 되면서 움직인다.

아래의 설정값은 시작과 끝의 지점을 알려 준다.

조금 고쳐야 할 것은 있지만. 우선 이걸로 써야 할듯 하다.

관련코드 :
Posted by gsi
:

[WPF] 마우스 이벤트

WPF 2007. 11. 29. 13:27 |

마우스 이벤트에 대해서..

객체가 있을때 마우스 이벤트를 사용해서 많은 기능을 처리해줘야 한다.

공부 하면서 알게된 내용을 적을려고 한다.

예를 들어서

Grid
   > Rectangle

이와 같은 객체가 있다고 가정하겠다.
그리고 마우스 이벤트는 Grid에 생성한다.
MouseLeftButtonUp 이벤트를 생성했을때 아래와 같은 함수가 생성되게 된다.

private void OnGridLButtonUp(object sender, MouseButtonEventArgs e)
{

여기서 sender는 Grid를 의미 하며, e는 마우스의 각종 상황들에 대한 정보를 가지고 있는다.

내가 여기서 해주고자 했던건 Grid의 내부 마우스 클릭 위치값을 가져 오기 위함이기 때문에
아래와 같은 작업을 해주었다.

마우스의 위치를 얻어 오기 위해서
Point pt = e.GetPosition((Grid)sender);
이런 구문을 사용했다.

GetPosition에는 현재 선택된 객체를 인자로 넘겨 주게 되면 그 객체에 대한 로컬 위치값이
나오게 되는거 같다.
Posted by gsi
: