using System.Data;
using System.Data.SqlClient;

// 연결문자열  
string ConnectionString = "server=localhost(or ServerIP);database=DB_Name;user id=sa;password=sa";

// 1. 데이터베이스 연결  
SqlConnection conn = new SqlConnection(ConnectionString);

// 2. 명령문 만들기  
string query = "SELECT * FROM table";
SqlCommand cmd = new SqlCommand(query, conn);

// 3. DataAdapter 개체 생성
SqlDataAdapter ad = new SqlDataAdapter();
ad.SelectCommand = cmd;

// 4. DataSet 개체 생성 및 데이터 채우기
DataSet ds = new DataSet();
ad.Fill(ds);

// 5. DataSet 개체를 GridView 컨트롤에 바인딩
GridView1.DataSource = ds;
GridView1.DataBind();
Posted by Gungume
,
using System.Data;
using System.Data.SqlClient;

// 연결문자열
string ConnectionString = "server=localhost(or ServerIP);database=DB_Name;user id=sa;password=sa";

// 1. 데이터베이스 연결
SqlConnection conn = new SqlConnection(ConnectionString);
conn.Open();

// 2. 명령문 만들기
string query = "SELECT * FROM table WHERE id = @id";
SqlCommand cmd = new SqlCommand(query, conn);

// 둘 중 하나 사용~
cmd.Parameters.Add("@id", SqlDbType.VarChar).Value = "id_Value";
cmd.Parameters.AddWithValue("@id", "id_Value");

// 3. 명령 실행
SqlDataReader reader = cmd.ExecuteReader();

// 4. 실행 결과 보여주기
while (reader.Read())
{    
    // 둘 중 하나 사용~    
    Console.WriteLine(reader[index]);    
    Console.WriteLine(reader["컬럼명"]);
}

// 5. 데이터베이스 닫기
reader.Close();
conn.Close();
Posted by Gungume
,

ListViewItem 복사

Language/C# 2008. 12. 16. 10:00
하나의 ListView에서 다른 ListView로 모든 데이터를 복사하고 싶을 때 아래와 같이 코딩을 하면 오류가 발생한다.

foreach (ListViewItem item in listViewA.Items)
{
     listViewB.Items.Add(item);
}

위의 코드 수행에 따른 오류 메시지를 보면 "두 개 이상의 위치에 'xxx' 항목을 추가하거나 삽입할 수 없습니다. 먼저 항목의 현재 위치에서 항목을 제거하거나 복제해야 합니다."라고 나온다.

오류메시지를 대략 보면 foreach 구문에서 item이 참조형식으로 받아오기 때문에 생기는 문제같다. 오류메시지에 나온 해결방법중 복제하는 방법을 코드로 옮기면 아래와 같다.

아래 코드를 실행해보면 원하는데로 동작한다.
foreach (ListViewItem item in listViewA.Items)
{
     listViewB.Items.Add((ListViewItem)item.Clone());
}


좀더 자세한 내용은 MSDN Forums(copy listview item to another listview.) 참조...
Posted by Gungume
,
이번에 졸업작품으로 만든 프로그램으로 C#으로 만들었다.

주제가 좀 평범해서 몇가지 경우에 대해서는 소켓통신 대신에 WMI를 사용했다는 것이 조금 다를뿐이다...

원래는 기본기능 외에 부가적인 기능과 PC재배치 등에 대한 기능을 좀더 유동적으로 만들려고 했는데 예정에 없던 산업체현장실습과 교육 등으로 인해 실제 개발에 투자한 시간이 몇주밖에 되지않아 기본기능만 구현했다;;;

나름 핵심기능은 WMI를 이용해서 PC의 전원 및 프로세스, 레지스트리 관리정도와 소켓통신을 이용한 원격제어 등이다...

아래는 전체시스템 구성도로 중앙서버(=메인서버)와 클라이언트(관리할 PC들)로 구성된다.

관리를 하기위한 기능은 대부분 서버에서 이루어지고, 클라이언트는 처음 실행시 학번을 통해서 로그인을 하고 이후에는 백그라운드로 실행되면서 서버에서 요청한 정보를 전송해주는 기능정도만 한다..

- 전체시스템 구성도 -
전체시스템 구성도



- 서버 -




- 클라이언트 -



- 프로세스 정보 -
WMI를 이용해서 원격지의 프로세스 정보를 얻어옴
왼쪽은 구현한 프로그램에서 얻어온 프로세스 정보이고 오른쪽은 윈도우의 작업관리자에서 얻어온 프로세스 정보
프로그램상에서 선택한 프로세스에 대한 Kill 가능~



- 원격탐색기 -
소켓통신을 이용해서 원격지의 폴더 & 파일 정보를 얻어옴
파일전송 기능을 넣고 싶었지만 시간이 부족했다;;;
역시 왼쪽은 구현한 프로그램, 오른쪽은 윈도우의 탐색기



- 화면캡쳐 -
소켓통신을 이용해서 원격컴퓨터의 화면을 캡쳐해옴
버튼 클릭에 따른 캡쳐 및 설정된 타이머간격으로 캡쳐가능
캡쳐된 화면 JPG, BMP, PNG 파일로 저장가능



- 윈도우최적화 -
WMI를 사용 원격컴퓨터의 레지스트리를 변경해서 윈도우최적화



- 원격제어 -
소켓통신을 이용한 원격제어
화면캡쳐를 이용한 원격제어
기본적인 키보드 & 마우스제어 가능

Posted by Gungume
,
C#을 이용한 정렬 알고리즘을 공부하다가 찾은 해외 사이트이다.

소스코드가 깔끔하게 잘되있고, 정렬외에도 유용한 자료가 많다.










Posted by Gungume
,


이번 포스팅에서는 소켓을 이용해서 이미지를 송수신하는 방법과 이때 필요한 데이터를 적절할 형식으로 형변환하는 과정에 대해 설명한다.

송수신될 이미지는 Bitmap 객체에 저장해서 사용하는데, 이 Bitmap 객체(=이미지 데이터)를 네트워크상에 보낼때는 바이트형으로 형변환을 한다.

이때 비트맵을 바이트형으로 형변환하는 이유는 네트워크상에서 이미지를 전송하는 방법이 여러가지가 있겠지만 간단하게 Socket 클래스의 Send(), Receive() 메소드를 사용한다면 이 메소드의 매개변수인 데이터버퍼가 byte[]형이기 때문이다.

이미지 송신측

이미지 수신측


우선 위의 데모프로그램을 설명하면 서버/클라이언트 구조로 작동을 하는데 Sender쪽에서 서버의 역할로 자신의 컴퓨터 전체화면을 캡쳐해서 이미지를 전송하고, Receiver쪽에서는 그 이미지를 받아서 화면에 출력해준다.
(전체화면 캡쳐하는 방법은 이전 글 참조...(클릭))

다음은 비트맵 이미지와 바이트형간의 형변환을 하는 소스의 일부이다.

// Bitmap To byte[]
Bitmap bitmap;	// 이미지가 저장된 bitmap객체
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, ImageFormat.Png);
ms.Position = 0;
byte[] data = ms.ToArray();


// byte[] To Bitmap
byte[] data;	// 전송된 이미지를 받은 버퍼
MemoryStream ms = new MemoryStream();
ms.Write(data, 0, (int)data.Length);
Bitmap bitmap = new Bitmap(ms);


소스를 보면 알겠지만 MemoryStream을 중간 매개체로 해서 간단하게 형변환을 한다.


먼저 비트맵을 바이트형으로 변환하는 소스(=Bitmap To byte[])부터 설명하겠다.

가장 위에 있는 bitmap 객체에 전송할 이미지 정보가 있다고 가정하고 이 이미지 정보를 메모리스트림에 저장한다. 그 이후에 메모리스트림의 ToArray()메소드를 이용해서 새로 생성한 byte[]형의 변수에 저장함으로써 형변환이 끝난다. 이렇게 형변환이 끝나면 최종 데이터인 data 변수를 Socket.Send() 메소드에 넣어줌으로써 이미지를 전송할 수 있다.


다음으로 바이트형을 비트맵으로 변환하는 소스(=byte[] To Bitmap)에 대해 설명하겠다.

Bitmap To byte[] 를 처리하는 과정과 거의 비슷한데, Socket.Receive()메소드를 통해서 전송된 이미지 정보를 data변수에 저장했다고 가정하고 이 데이터를 메모리스트림에 저장한다. 그 다음에 Bitmap 객체를 생성하면서 생성자에 메모리스트림 객체를 넣어줌으로써 간단히 형변환이 끝난다. 이렇게 형변환이 끝난 최종 데이터인 bitmap 객체를 이용해서 이미지 정보를 사용할 수 있다.

Source: https://github.com/gungume/BlogSamples/tree/master/ImageTransport
(사용언어 / 제작툴 / .Net Framework버전 : C# / VS2008 / 3.5)

Posted by Gungume
,


이번 포스팅에서는 현재 윈도우의 전체화면을 캡쳐하는 방법과 캡쳐된 화면을 파일로 저장하는 방법을 설명한다.

우선 아래 그림은 데모프로그램을 이용해서 화면을 캡쳐하고 Picturebox 컨트롤을 이용해서 캡쳐된 화면을 출력해준 것이다.

캡쳐화면 예시



다음은 화면을 캡쳐하고 저장하는 주요 소스이다.

// Capture
int width = Screen.PrimaryScreen.Bounds.Width;
int height = Screen.PrimaryScreen.Bounds.Height;

Size size = new Size(width, height);
bitmap = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(0, 0, 0, 0, size);

// Save
bitmap.Save("FileName.jpg", System.Drawing.ImageFormat.Jpeg);

위의 소스를 간단히 설명하면 다음과 같다.

우선 화면을 캡쳐하는 것부터 설명하면, 이 예제는 전체화면을 캡쳐하는 것이기에 우선 현재 윈도우의 해상도를 얻어와야 한다. 해상도를 얻는 방법은 "Screen.PrimaryScreen.Bounds"에 있는 Width, Height 속성을 통해서 간단히 얻을 수 있다.
(해상도 얻는 방법은 이전 글 참조...(클릭))

다음으로 얻어온 해상도를 이용해서 해당 크기만큼 Size, Bitmap 객체를 생성하고, Graphics 객체를 생성한다.

마지막으로 Graphics 객체의 CopyFromScreen() 메소드를 이용하면 bitmap 객체에 현재 윈도우의 화면이 그대로 캡쳐되서 저장이된다. 저장된 bitmap 객체를 이용해서 Picturebox 컨트롤을 이용해 화면에 표시를 해주거나 Save() 메소드를 이용하면 파일로 저장이 가능하다.

이제 캡쳐된 화면을 파일로 저장하는 부분을 설명하면, 단순히 Bitmap 객체의 Save() 메소드를 사용하는데, 소스를 보면 알수 있듯이 별다른 설명이 필요 없을 정도로 직관적이다.

Save() 메소드는 위의 예제와 달리 2번째 매개변수인 파일형식을 적어주지 않고 매개변수로 파일명 하나만 적어줘도 파일로 저장이 가능하다.

Source: https://github.com/gungume/BlogSamples/tree/master/ScreenCaputre
(사용언어 / 제작툴 / .Net Framework버전 : C# / VS2008 / 3.5)

※ C#을 이용한 화면캡쳐와 관련해서는 데브피아 C#마을 강좌&팁 게시판에 있는 윤성민님의 "C#에 대한 낙서 13 (캡쳐 프로그램제작 3) (클릭)"를 참고했다.


Posted by Gungume
,
현재 윈도우 해상도 얻기
Size Bounds = Screen.PrimaryScreen.Bounds.Size;
MessageBox.Show(Bounds.ToString());
(결과) Width=2560, Height=1600

작업 표시줄 제외한 윈도우 영역 크기 얻기
Size WorkingArea = Screen.PrimaryScreen.WorkingArea.Size;
MessageBox.Show(WorkingArea.ToString());
(결과) Width=2560, Height=1570

※ 결과 : 2560*1600 해상도에서 테스트 한 결과
Posted by Gungume
,

VC++환경에서 메모리릭을 찾기 위한 방법은 디버그 모드에서 CRT(C runtime library)디버그 함수를 사용


1. 밑에 선언하는 방법


- _CrtDumpMemoryLeaks()함수로 메모리릭 찾기

  #define CRTDBG_MAP_ALLOC

  #include <stdlib.h>

  #include <crtdbg.h>

  //위의 순서를 반드시 지켜야 함


  void memleak()
  {
      // 메모리가 누수가 일어나는 부분

  }                                                    


  void main()
  {
   memleak();

  _CrtDumpMemoryLeaks();
  }

_CrtDumpMemoryLeaks() 함수를 사용하여 메모리릭을 찾는 방법을 사용시는 반드시 메모리릭이 발생된 이후 시점에서 이 함수를 호출해야만 누수된 메모리 블록 정보를 확인할 수 있다.


2. 위에 선언하는 방법

- _CrtSetDbgFlag()함수로 메모리릭 찾기==> 프로그램 시작부분에 함수 호출

  _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); 호출


#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <string.h>
#include <crtdbg.h>

void memleak()
{
  ... // (메모리 누수가 일어나는 부분)

}

void main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
memleak();
}


[옵션들]

_CRTDBG_ALLOC_MEM_DF - 메모리 할당이 일어나는 경우 추적하게 해줍니다.

_CRTDBG_LEAK_CHECK_DF - 종료시에 _CrtDumpMemoryLeaks()를 호출하여 메모리 누수 정보를 표시해 줍니다.

_CRTDBG_DELAY_FREE_MEM_DF - 실행중간에 메모리가 해제 된다고 하더라도 실제로 해제를 실행하지 않고 종료 시 해제를 하게 합니다.

_CRTDBG_CHECK_ALWAYS_DF - 모든 할당 및 할당 취소에서 _CrtcheckMemory를 호출하여 실행속도는 지연되지만 오류를 신속하게 찾아냅니다.

_CRTDBG_CHECK_CRT_DF - CRT내부도 메모리 탐지에 포함 시킵니다.


3. New메모리에 CRT기능 넣기

위에 1,2번 기준으로 디버깅을 돌려보면은 메모리 누수 정보는 나오지만 new 메모리 할당시에는

정확한 정보가 나오지 않는다

아래와 같이 고치면 정확한 정보가 뜰 것이다.


#include <stdio.h>
#include <string.h>
#include <crtdbg.h>

//디버그용  new
#ifdef _DEBUG
#define new new(_CLIENT_BLOCK, __FILE__, __LINE__)
#endif

int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);


...


return 0;
}


[참고]

기본적으로 MFC에서는 위 코드를 활용할 필요가 없다.

왜냐면 메모리 누수 관련 코드가 만들자마자 자동 삽입되기때문이다.


출처 : 네이버 게임 프로그래밍 카페

Posted by Gungume
,

1. 모든 소스의 선두에 아래 순서대로 입력한다.

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)


- 순서가 다르면 안됨

- stdafx.h(미리 컴파일된 해더)에 넣어도 된다.



2. Main()함수 - 맨 처음 시작하는 함수

첫번째 라인에 아래와 같이 적는다.

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);



3. VS에서 디버그 모드로 시작(F5)하고, 스스로 종료해야 한다.

(Shift + F5를 하지 말라는 의미임)



4. 기타

- 직접 테스트 해 본 결과로는 Malloc도 가능하다.

 (#define new 없으면 new만 된다..-_-a 잘 이해 안됨)

- CRT로는 전체 CallStack을 찍어주지 않고

  최종적으로 new를 사용한 곳을 찝어주는 것 같다.

  만약 이미 소스에서 new를 다르게 만들어 사용한다면 역시나 찾을 수 없게 될 듯.




[예제]

#include "stdafx.h" //여기엔 이 두가지만 있다.

//#include <iostream>
//#include <tchar.h>

//만약 아래의 내용을 iostream보다 먼저 쓰는 경우 Error가 난다.


#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)


int _tmain(int argc, _TCHAR* argv[])
{
       _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
       char* pNew = NULL;
       pNew = new char;


       char* pMalloc = NULL;
       pMalloc = (char*)malloc( sizeof(char) * 10 );


       char* pAA = NULL;
       pAA = new char[100];
       delete [] pAA;


       return 0;
}


[잘 된 결과]

- 아래처럼 실제로 사용한 파일명과 할당한 라인 수가 나와야 제대로 된 것

Detected memory leaks!
Dumping objects ->
d:\study myself\디버깅\crtmemoryleak\crtmemoryleak.cpp(30) : {44} normal block at 0x00372D80, 10 bytes long.
Data: <          > CD CD CD CD CD CD CD CD CD CD
d:\study myself\디버깅\crtmemoryleak\crtmemoryleak.cpp(24) : {43} normal block at 0x00372D40, 1 bytes long.
Data: < > CD
Object dump complete.
'[840] CRTMemoryLeak.exe: 네이티브' 프로그램이 0 (0x0) 코드에서 끝났습니다.


[잘못된 결과]

- 순서가 잘못되거나 하면 crtdbg.h파일의 라인수가 나온다.

Detected memory leaks!
Dumping objects ->
c:\program files\microsoft visual studio .net 2003\vc7\include\crtdbg.h(689) : {43} normal block at 0x00372D40, 1 bytes long.
Data: < > CD
Object dump complete.


출처 : 네이버 블로그였는데 까먹음;;;

Posted by Gungume
,