BOOTMGR is missing Press Ctrl+Alt+Del to restart라고 뜰때..

XP 시절에는 fixmbr, fixboot 정도면 다 되던것이 BCD등이 들어가면서 상당히 복잡한 느낌이네요.

누구나 따라하실 수 있도록 스텝바이스텝으로 설명을 해보려 합니다.

*부팅 자동복구를 통해 복구하는 것이 제일 간단하겠지만, 지 마음대로 시스템 파일을 갈아엎는 것이 마음에 들지 않으시는 분이나 자동복구를 했는데 '문제를 해결할 수 없습니다' (= 이건 뭐 수동으로 하라는 말이죠..) 가 떴는데, 윈도우 다시 깔기는 싫으신 분들..

*윈도우 PE를 이용할 경우 cmd 를 열면 동일하게 진행할 수 있습니다. GUI가 되니 더 쉽죠.

그런데 PE를 또 만들어야 하니 여기서는 설치 디스크를 이용하는 방법을 설명합니다.


1. 하드디스크 여러개를 사용하는 경우,

일단 윈도우가 설치된 하드디스크를 SATA 1번 포트 (메인보드에 보면 번호가 써있습니다.)에 꼽아주세요! 

*이 단계를 생략할 경우 부트섹터를 복구해놔도 부팅이 안되거나, 드라이브 문자가 뒤섞이거나 하는 문제가 생깁니다. 

* 그냥 윈도우7 설치할때도, 애먼 하드에다가 윈도우가 깔리는 현상을 방지하려면 꼭 이렇게 해줘야 합니다.

2. 윈도우 7 / Windows Vista 설치 USB나, 설치 DVD를 이용해 부팅합니다. (PE로 부팅하신 뒤 명령 프롬포트 이용하셔도 동일합니다.)

3. 초기 화면에서 Shift+F10 명령 프롬포트에 진입.

4. diskpart

5. list disk

*당연히 윈도우가 설치된 파티션이 disk 0.

6. select disk 0

7. list partition

*Windows가 설치된 파티션 번호 (*디스크 번호랑 다릅니다.)

*설치 디스크로 부팅 시 드라이브 문자가 뒤섞이기 때문에 (주로 C이긴 하지만) 용량 등으로 윈도우가 설치되어있는 파티션을 구분해야합니다! 구분 하실때 detail disk 를 하시면 디스크 내의 파티션에 대한 자세한 정보가 나와서 큰 도움을 줄겁니다.

* 정 구분이 안가시면 8번~9번 단계를 디스크 내에 존재하는 모든 파티션 (partition 1 ~partition n)에 해주면 됩니다. 

8. select partition 1

9. active

*이 단계는 파티션을 부팅디스크로 사용될 수 있도록 활성파티션 표시하는 것입니다.

10. exit - diskpart를 빠져나옵니다.

11. 다음을 입력합니다 : bootsect c:\ /nt60 /mbr

*c:\는 windows가 설치된 파티션으로 바꿔주세요. 대개 c:\

12.. 다음을 입력합니다 : bootrec /fixmbr

13 . 다음을 입력합니다 : bootrec /fixboot

*이 단계에서 element not found / 요소를 찾을 수 없습니다. 라는 오류가 뜨는 경우,

4번~9번 단계에서 진행이 잘못된 것입니다. 다시 한번 찬찬히 진행해 주세요.

14. 다음을 입력합니다 : bootrec /rebuildbcd

15. 확인하는 단계가 뜨는데 (Yes/No) 전부다 Y 를 입력하고 엔터를 누릅니다.


왠만한 경우 이 단계까지 마치면 부팅이 됩니다.

Windows가 설치되어있음에도 컴퓨터 복구 메뉴에서 윈도우 감지가 안된다거나 하는 문제도 이 절차를 거치면 해결이 됩니다.

윈도우 설치가 감지가 된다면 바로 부팅 복구 (자동복구) 기능을 이용할 수 있지요.


bcdboot c:\windows /l ko-kr 하면 BCD 생깁니다.

------------------------------------------------------------

지금 발생하는 문제의 원인은, 예약파티션(윈도우7을 설치시 생기는 100MB짜리 파티션)이 제거되어서 부팅파티션과 부팅에 관련된 파일(bcd,bootmgr,..등)을 PC가 찾을수 없어서 다음과 같은 문제가 발생했습니다.


다음의 과정을 시도해보면 정상 부팅을 할 수 있을것입니다.

1. windows 7 DVD로 부팅한다.

2. 부팅 선택메뉴에서 '복구모드'를 선택한다.

3. 자동복구를 시도해본다.

4. 자동복구가 안될경우 다음과 같이 해본다.

5-1. 명령프롬프트(cmd)를 실행한다.

5-2. 'diskpart'명령 실행

5-3. 'list disk'명령 실행

5-4. "select disk '번호'" 명령어로 윈도우가 설치된 하드 선택

'번호':윈도우가 설치된 하드의 디스크 번호

5-5. 'list partition'명령 실행

5-6. "select partition '번호'" 명령어로 윈도우가 설치된 파티션 선택

'번호':윈도우가 설치된 하드의 파티션 번호

5-7. 'active'명령 실행 - 활성 파티션 설정 완료!

5-8. 'exit'명령어로 빠져나옴.

6-1. 윈도우가 설치된 하드 드라이브로 이동

예)c: / 참고)이하내용 c드라이브를 기준으로 설명함.

6-2. 'bcdboot c:\windows /s c:' 명령 실행

6-3. 'bcdboot c:\windows /l ko-KR'명령 실행

7. 재부팅해본다.

===================================================================


Bootsect 명령에 의한 MBR 복구..


윈도우7 설치cd 또는 복구 디스크 부팅해서 복구 모드로 들어갑니다. 콘솔창 띄우시구

Bootsect /nt60 c: /mbr

Bootsect.exe는 하드 디스크 파티션의 마스터 부팅 코드를 업데이트하여 Bootmgr과 NTLDR(NT 로더) 사이를 전환합니다. 이 도구를 사용하면 컴퓨터의 부팅 섹터를 복원할 수 있습니다. 이 도구는 FixFAT 및 FixNTFS를 대체합니다.


Bootsect 명령


Bootsect에서는 다음 명령줄 옵션을 사용합니다.

bootsect.exe {/help | /nt52 | /nt60} {SYS | ALL | } [/force] /mbr

예를 들어 NTLDR과 호환되는 마스터 부팅 코드를 볼륨 레이블 E에 적용하려면 다음 명령을 사용합니다.


bootsect.exe /nt52 E:

명령줄 옵션 설명


/help

사용 지침을 표시합니다.


/nt52

NTLDR과 호환되는 마스터 부팅 코드를 SYS, ALL 또는 에 적용합니다. SYS, ALL 또는 에 설치된 운영 체제는 Windows® XP여야 합니다.


/nt60

Bootmgr과 호환되는 마스터 부팅 코드를 SYS, ALL 또는 에 적용합니다. SYS, ALL 또는 에 설치된 운영 체제는 Windows Vista®여야 합니다.


SYS

Windows를 부팅하는 데 사용된 시스템 파티션의 마스터 부팅 코드를 업데이트합니다.


ALL

모든 파티션의 마스터 부팅 코드를 업데이트합니다. ALL은 각 볼륨에 대한 부팅 코드를 반드시 업데이트하지는 않습니다. 대신 이 옵션은 Windows 부팅 볼륨으로 사용할 수 있는 볼륨의 부팅 코드를 업데이트하며, 이때 기존 디스크 파티션과 연결되지 않은 동적 볼륨은 제외됩니다. 이러한 제한은 부팅 코드가 디스크 파티션의 시작 부분에 있어야 하기 때문입니다.



/force

부팅 코드를 업데이트하는 동안 볼륨을 강제로 분리합니다. 이 옵션을 사용할 때는 주의해야 합니다.


Bootsect.exe에서 단독으로 볼륨에 액세스할 수 없는 경우 다시 부팅하기 전에 파일 시스템에서 부팅 코드를 덮어쓸 수 있습니다. Bootsect.exe는 항상 업데이트하기 전에 볼륨 잠그기와 분리를 시도합니다. /force를 지정하면 초기 잠금이 실패할 경우 강제 분리를 시도합니다. 예를 들어 대상 볼륨의 파일을 현재 다른 프로그램에서 열어 놓은 경우 잠금이 실패할 수 있습니다.


성공하면 초기 잠금이 실패해도 강제 분리를 통해 단독 볼륨 액세스 및 안정적인 부팅 코드 업데이트가 가능합니다. 동시에 강제 분리는 대상 볼륨의 파일에 대해 열려 있는 핸들을 모두 무효화합니다. 그 결과 이러한 파일을 연 프로그램에서 예기치 않은 동작이 수행될 수 있으므로 이 옵션을 사용할 때는 주의해야 합니다.


/mbr

SYS, ALL 또는 에서 지정한 파티션을 포함하는 섹터가 0인 디스크에서 파티션 테이블을 변경하지 않고 마스터 부트 레코드를 업데이트합니다. 이를 /nt52 옵션과 함께 사용하면 마스터 부트 레코드가 Windows Vista 이전 운영 체제와 호환됩니다. 이를 /nt60 옵션과 함께 사용하면 마스터 부트 레코드가 Windows® 7, Windows Vista, Windows Server® 2008 또는 Windows Server® 2008 R2와 호환됩니다.


================================================


windows xp mbr vbr 복구


1 windowsxp cd 부팅 복구모드

2 fixboot,fixmbr 실행



-mbr 복구 

fixmbr c:


-vbr 복구

fixboot c:


-ntldr 복구

copy d:\i386\ntldr c:\

copy d:\i386\nydetect.com c:\

bootcfg/rebuild



==============================================

windows RE(Windows 복구 환경)에서 Bootrec.exe 도구를 사용하여 Windows Vista의 다음 항목에서 발생하는 문제를 해결하고 복구할 수 있습니다.


MBR(마스터 부트 레코드)

부팅 섹터

BCD(부팅 구성 데이터) 저장소


참고 Windows RE를 사용하여 시작 문제를 해결할 때 먼저 시스템 복구 옵션 대화 상자에서 시동 복구 옵션을 시도해야 합니다. 시동 복구 옵션으로 문제가 해결되지 않거나 더 많은 단계를 수동으로 해결해야 하는 경우 Bootrec.exe 도구를 사용하십시오.


Bootrec.exe 도구를 실행하려면 Windows RE를 시작해야 합니다. 이렇게 하려면 다음과 같이 하십시오.


디스크 드라이브에 Windows Vista 설치 디스크를 넣은 다음 컴퓨터를 시작합니다.

메시지가 나타나면 키를 누릅니다.

언어, 시간, 통화, 키보드 또는 입력 방법을 선택하고 다음을 누릅니다.

컴퓨터 복구를 누릅니다.

복구할 운영 체제를 누르고 다음을 누릅니다.

시스템 복구 옵션 대화 상자에서 명령 프롬프트를 누릅니다.

Bootrec.exe를 입력한 다음 Enter 키를 누릅니다.


참고 Windows Vista DVD에서 컴퓨터를 시작하려면 컴퓨터가 DVD 드라이브에서 시작하도록 구성되어 있어야 합니다. DVD 드라이브에서 시작되도록 컴퓨터를 구성하는 방법에 대한 자세한 내용은 컴퓨터에 포함되어 있는 설명서를 참조하거나 컴퓨터 제조업체에 문의하십시오.

위로 가기

Bootrec.exe 옵션

Bootrec.exe 도구는 다음 옵션을 지원합니다. 해당 상황에 적합한 옵션을 사용하십시오.


참고 BCD를 다시 빌드해도 시작 문제가 해결되지 않으면 BCD를 내보내고 삭제한 다음 이 옵션을 다시 실행할 수 있습니다. 이렇게 하면 BCD가 완전히 다시 빌드됩니다. 이렇게 하려면 Windows RE 명령 프롬프트에서 다음 명령을 입력하십시오.


bcdedit /export C:\BCD_Backup

c:

cd boot

attrib bcd -s -h -r

ren c:\boot\bcd bcd.old

bootrec /RebuildBcd


/FixMbr

/FixMbr 옵션은 Windows Vista와 호환되는 MBR을 시스템 파티션에 기록합니다. 이 옵션은 기존 파티션 테이블을 덮어쓰지 않습니다. MBR 손상 문제를 해결해야 하거나 MBR에서 비표준 코드를 제거해야 하는 경우 이 옵션을 사용하십시오.

/FixBoot

/FixBoot 옵션은 Windows Vista와 호환되는 부팅 섹터를 사용하여 새 부팅 섹터를 시스템 파티션에 기록합니다. 다음 조건 중 하나에 해당하면 이 옵션을 사용하십시오.


부팅 섹터가 비표준 Windows Vista 부팅 섹터로 대체되었습니다.

부팅 섹터가 손상되었습니다.

Windows Vista가 설치된 후 이전 Windows 운영 체제가 설치되었습니다. 이 경우에 Windows 부팅 관리자(Bootmgr.exe) 대신 Windows NTLDR(NT 로더)을 사용하여 컴퓨터가 시작됩니다.


/ScanOs

/ScanOs 옵션은 Windows Vista와 호환되는 설치 디스크를 모두 검색합니다. 또한 이 옵션은 BCD 저장소에 현재 없는 항목을 표시합니다. 부팅 관리자 메뉴에 표시되지 않는 Windows Vista 설치가 있으면 이 옵션을 사용합니다.

/RebuildBcd

/RebuildBcd 옵션은 Windows Vista와 호환되는 설치의 디스크를 모두 검색합니다. 또한 이 옵션은 BCD 저장소에 추가할 설치를 선택할 수 있도록 합니다. BCD를 완전히 다시 빌드해야 하는 경우 이 옵션을 사용하십시오. 




---------------------------------------------------------------------------------

DVD부팅시 EMS사용가능이란 무엇을 말하나?

EMS = Emergency Management Services = 응급 관리 서비스

가끔 System Repair Disc (약 145Mb) 또는 ERD 6.0 (6.5) or ERD Commander 2006 (2007)이란 말을 들어보셨을 것입니다. 

아시다시피 이것은 어떤 이유에 의하여 system Malfunction으로 복구가 필요하면 Install Boot DVD 를 넣고 복구를 합니다 

그리고 System Recovery Options에서 해당 복구를 선택하여 시행합니다. 

따라서 복구기능이 함축된 Win nstall DVD에 메뉴선택으로 각각 x86(x32)용 x64용.

--------------------------------------------------------------------------------


NTLDR is missing

NTLDR NT 계열에서 사용되는 부트 로더 입니다. 


NTLDR는 NT 로더(NT Loader)의 준말로, 마이크로소프트 윈도 NT 계열 운영 체제를 위한 시동 로더이다. 이를테면 윈도 XP와 윈도 서버 2003을 들 수 있다. NTLDR은 보통 원본의 하드 디스크 드라이브에서 실행되지만 CD-ROM, USB 플래시 드라이브, 플로피 디스크와 같은 휴대용 기억 장치에서도 실행할 수 있다. NTLDR은 또한 어떠한 파일의 적절한 시동 섹터가 주어진다면 NT 기반이 아닌 운영 체제를 불러들일 수도 있다.


NTLDR은 적어도, 시스템 볼륨 위에 다음의 두 개의 파일들이 필요하다:


NTLDR: 기본 시동 로더 자체이다.

boot.ini: 시동 메뉴를 위한 구성 옵션을 포함하고 있다. (윈도 비스타 이후의 운영 체제부터는 이를 포함하지 않는다.)


NT 기반의 운영 체제에서 로드할 경우 ntdetect.com이 반드시 존재해야 한다. (정확히 말하면 NTLDR만이 실제로 필요하지만 boot.ini가 존재하지 않으면 NTLDR은 기본적으로 첫 하드 드라이브의 첫 파티션에 있는 c:\windows 디렉터리를 잡게 된다. 가정의 많은 데스크톱 컴퓨터들은 이러한 구성을 따르며 boot.ini 파일이 없어지면 이러한 파일이 존재하지 않는다는 오류가 뜨면서 윈도로 성공적으로 시동된다.)


윈도 NT 포맷 명령에 의해 디스크에 기록된 볼륨 시동 레코드는 NTLDR 프로그램을 불러들이고 실행한다.


윈도 비스타와 윈도 서버 2008의 경우, NTLDR이 아닌 다른 시동 로더를 사용한다. 시동 로더 기능은 다음의 두 가지 새로운 구성요소로 대체되어 있다.

winload.exe

윈도 시동 관리자


----------------------------------------------------------

시작 프로세스


시동할 때, 로드 프로그램의 NTLDR은 다음의 순서를 따른다:


시동 드라이브의 파일 시스템에 접근한다. (현재로써는 FAT 또는 NT 파일 시스템 NTFS)

hiberfil.sys를 발견하여 최대 절전 모드의 이미지를 찾는다면, 이에 대한 내용은 메모리로 불러들이고 시스템이 꺼질 때 재개된다.

hiberfil.sys를 발견하지 않은 경우, boot.ini를 읽어내고 (역자 주: 여러 개의 운영 체제가 설치되어 있는 등의 경우) 시동 메뉴를 사용자에게 보여준다.

NT 기반이 아닌 운영 체제가 선택되면, NTLDR은 boot.ini 안에 나열된 연결 파일을 불러들이고 제어권을 제공한다. 도스 기반의 도스로 시동하거나 연결 파일을 따로 지정하지 않으면 연결 파일로 bootsect.dos를 찾는다.

NT 기반의 운영 체제가 선택되면, NTLDR은 ntdetect.com을 실행하여 사용자 컴퓨터의 하드웨어에 대한 정보를 얻는다. (ntdetect가 하드웨어 감지 도중에 멈추는 것을 대비하여, 마이크로소프트 지원[1]에서 찾을 수 있는 ntdetect.chk라고 불리는 디버그 버전이 있다.)

Ntoskrnl.exe를 실행하여 ntdetect.com가 반환한 정보를 내보낸다.[1]

----------------------------------------------------------

(윈도 XP 이전 운영 체제에서) 사용자의 실수 혹은 바이러스 이외의 환경요인으로 인해서 NTLDR 파일이 삭제되거나 변형되면 외관상으로는 아무런 문제도 없어 보이지만, 운영 체제를 다시 시작하면 부팅에 실패하게 되고, 'ntldr is missing, Press Ctrl+Alt+Del' 이라는 메시지가 출력된다.


그러나 저 메시지가 뜬다고 반드시 NTLDR 파일이 삭제되었다고 보기엔 어렵다(파일을 불러오는 중에 알 수 없는 이유로 일시적인 오류를 일으켜 나타나는 메시지일 가능성도 있기 때문이다.) 하지만 출력된 메시지의 방법으로도(재부팅을 해도) 부팅에 실패하고 같은 메시지가 나온다면, 삭제 혹은 변형을 의심할 수 있다. 그러나 일반적인 해결 방법은 없으며, 새로 윈도 운영 체제를 설치해야 한다.


(같은 운영 체제의 정상 PC가 있을 경우에는 부팅에 실패하는 하드디스크를 연결한 다음, 같은 O/S의 정상 PC에 있는 NTLDR 파일을 부팅에 실패하는 하드 디스크에 복사하여 되돌리는 방법도 있다. 하지만 단순히 NTLDR 파일 이상으로 나타나는 문제가 아닐 수 있으므로, 재설치를 권장한다.)


이런 문제로 인해 윈도 비스타 이상 운영 체제 부터는 새로운 부트 로더를 사용한다.

----------------------------------------------------------

boot.ini


NTLDR은 사용자가 어느 운영 체제로 시동할 것인지 메뉴를 띄워 준다. 윈도 NT 및 NT 기반 운영 체제에서는, 커널에 대해 사용자가 미리 구성한 옵션들을 무시할 수도 있다. 이러한 메뉴 옵션들은 boot.ini에 저장되는데, NTLDR과 같은 곳(같은 디스크의 루트)에 위치해 있다.


NT 기반의 운영 체제에서, 운영 체제의 위치는 고급 RISC 컴퓨팅 (ARC) 경로로 쓰여져 있다.


boot.ini는 다음의 파일 특성을 가지면서 사용자 구성을 보호한다.: 시스템, 숨김, 읽기 전용. 이 파일의 내용을 편집하기 위해서는 다음의 과정을 따르면 된다.


콘솔에서 다음의 명령어를 입력한다: attrib -s -h -r boot.ini. (-s는 시스템 특성을, -h는 숨김 특성을, -r은 읽기 전용 특성을 없앤다)

폴더 옵션에서 "숨김 파일 및 폴더 보기"에 체크하고 "보호된 운영 체제 파일 숨김"의 체크를 없앤 다음, 루트 디렉터리에 표시되는 boot.ini 파일의 특성을 속성에서 변경한다.

더 보안적인 기능의 편집을 위해서는 콘솔에서 bootcfg 명령어를 사용하는 것이다.

시작→실행→msconfig를 사용하여 시스템 구성 유틸리티의 시동 환경을 수정할 수 있다. 이것은 boot.ini가 없는 윈도 비스타에서도 마찬가지이다.


bootsect.dos는 도스를 불러들이기 위해 NTLDR이 불러들이는 시동 섹터이다. 특정한 파일이 지정되지 않으면, NTLDR은 bootsect.dos를 불러들인다.

=================================================
bootmgr
bcdboot
==================================================

mbr pbr vbr

PBR은 여러 이름으로 불리는데 다른 이름으로는 BPB라고도 한다. 옛날 도스 시절에 BIOS 콜을 통해 파티션에 대한 정보를 얻어오고 처리하고 했는데, 그 기본 정보가 되는 블럭이라서 저런 이름이 붙은 것 같다. 일단 여기서는 PBR이라고 하겠다.

PBR과 MBR의 차이는 무엇일까? MBR은 하나만 존재하며 섹터 0에만 있고, PBR은 각 파티션의 시작에 존재하며 FAT에 대한 정보를 포함하고 있다는 것이 다르다

vbr volume boot record
--------------------------------

MBR(Master Boot Record)은 PC에서 사용되는 포맷된 하드디스크 드라이브의 첫 번째 섹터의 내용을 말합니다.

// MBR 섹터에 있는 파티션 테이블 구조

struct PartTable

{ // OFFSET: 446~461

BYTE Bootable; // 446 0x1BE

BYTE StartHead; // 447 0x1EF

WORD StartCylSec; // 448 0x1C0

BYTE Type; // 450 0x1C2

BYTE EndHead; // 451 0x1C3

WORD EndCylSec; // 452 0x1C4

long LBA_Begin; // 454 0x1C6

long Size; // 458 0x1CA

};


[Bootable] BYTE

맨 처음 바이트인 bootable은 해당 파티션이 부팅 가능한 것인지를 나타내는 것입다. 이 값은 부팅 가능한 경우 80h, 불가능한 경우 00h가 설정됩니다.


[StartHead-StartCylSec] BYTE-WORD

다음 항목인 start_drv_head와 start_sec_cyl은 파티션 정보 확인 후 부트 레코드를 읽어오기 위해 필요한 부트 섹터의 어드레스를 나타냅니다. 그 내용은 Int11 인터럽트의 파라미터로 바로 사용될 수 있는 형식으로 되어 있습니다.

출처 : http://hyora.logu2.com

사업자 정보 표시
가나소프트 | 김용유 | 충남 천안시 동남구 목천읍 서리2길 42-1 | 사업자 등록번호 : 312-33-14797 | TEL : 070-8659-0316 | Mail : yykim@gana-soft.com | 통신판매신고번호 : 12390123호 | 사이버몰의 이용약관 바로가기
void DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap, LONG xStart, LONG yStart, COLORREF cTransparentColor)  
{  
BITMAP bm;  
COLORREF cColor;  
HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;  
HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;  
HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;  
POINT ptSize;  
/* 초기화 작업 */
hdcTemp = CreateCompatibleDC(hdc);  
SelectObject(hdcTemp, hBitmap); // 비트맵 선택

GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);  
ptSize.x = bm.bmWidth; // 비트맵 가로 크기 
ptSize.y = bm.bmHeight; // 비트맵 세로 크기
DPtoLP(hdcTemp, &ptSize, 1); // 디바이스를 논리적 위치로 변경

// 작업용 DC 생성
hdcBack = CreateCompatibleDC(hdc);  
hdcObject = CreateCompatibleDC(hdc);  
hdcMem = CreateCompatibleDC(hdc);  
hdcSave = CreateCompatibleDC(hdc);  

// 흑백 연산 (and,or연산)에 필요한 비트맵 생성 
bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);  
bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);  
// 작업용 비트맵들 생성 
bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);  
bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);  

// 각 비트맵 삭제 위한 old 비트맵 생성 
bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack);  
bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);  
bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem);  
bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave);  

//그려질 DC와 생성된 임시DC의 맵핑 모드 일치화 
SetMapMode(hdcTemp, GetMapMode(hdc));  

// 원본 보전 작업
BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);  

// 투명화 시킬 색을 Tempdc의 배경색으로 설정,
// 이때 SetBkColor의 리턴 값으로 원본 색 저장
cColor = SetBkColor(hdcTemp, cTransparentColor);  

/* 주어진 비트맵의 투명색(BkColor로 지정된)은 힌색으로,
나머지는 검은색으로하여 BlackWhitedc_1에 저장 */
BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,   
SRCCOPY);  

// 배경 색을 원본 색상 DC를 가져오기
SetBkColor(hdcTemp, cColor);  

// BlackWhitedc_1를 이용 투명 영역(검은색), 비투명 영역(힌색)으로 된 DC생성 
BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,   NOTSRCCOPY);  

// 그려질 hdc에서 비트맵이 위치할 곳의 배경을 작업용 DC로 이동 
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY);  
//BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, 0, 0, SRCCOPY);  

// 그려질 배경과 and 연산을 통해 배경투명구현(힌색 소멸), 비투명 영역은 검은 색으로
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);  

// 주어진 비트맵과 and 연산을 통해 투명부분(검은색으로), 비투명은 그대로
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);  

// 위에서 만든 2개의 DC(Workdc, Tempdc)의 or 연산을 통해 두 DC결합 
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);  

//  결과를 표시
 BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY);  

//  원본을 임시 DC에 복구
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);  

// 메모리에 있는 각 비트맵 삭제
DeleteObject(SelectObject(hdcBack, bmAndBack));  
DeleteObject(SelectObject(hdcObject,bmAndObject));  
DeleteObject(SelectObject(hdcMem, bmAndMem));  
DeleteObject(SelectObject(hdcSave, bmSave));  
DeleteObject(SelectObject(hdcBack, bmBackOld));  
DeleteObject(SelectObject(hdcObject,bmObjectOld));  
DeleteObject(SelectObject(hdcMem, bmMemOld));  
DeleteObject(SelectObject(hdcSave, bmSaveOld));  

// 각 DC삭제 
DeleteDC(hdcBack);  
DeleteDC(hdcObject);
DeleteDC(hdcMem);    
DeleteDC(hdcSave);  
DeleteDC(hdcTemp);  
DeleteDC(hdc); // 자신의 DC를 삭제하지 않으면 GDI 객체는 계속 늘어나게 된다..
 }  


/// 사용 예시..
DrawTransparentBitmap(::GetDC(((CStatic*)GetDlgItem(컨트롤))->GetSafeHwnd()), (BMP), 0, 0, 색상);

// 미리 정의해 놓고 사용하면 좀더 편리함...
#define TRANS_BITMAP(CTRL, BMP); DrawTransparentBitmap(::GetDC(((CStatic*)GetDlgItem(CTRL))->GetSafeHwnd()), (BMP), 0, 0, BLACK);


사업자 정보 표시
가나소프트 | 김용유 | 충남 천안시 동남구 목천읍 서리2길 42-1 | 사업자 등록번호 : 312-33-14797 | TEL : 070-8659-0316 | Mail : yykim@gana-soft.com | 통신판매신고번호 : 12390123호 | 사이버몰의 이용약관 바로가기

/* =-=-=-=-=-=-=-=-=-=-=-=-=-= Window Messages =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#define WM_NULL           0x0000
#define WM_CREATE                   0x0001
#define WM_DESTROY                  0x0002
#define WM_MOVE                     0x0003
#define WM_SIZE                     0x0005
#define WM_ACTIVATE                 0x0006

/* WM_ACTIVATE state values */
#define     WA_INACTIVE             0
#define     WA_ACTIVE               1
#define     WA_CLICKACTIVE          2

#define WM_SETFOCUS                 0x0007
#define WM_KILLFOCUS                0x0008
#define WM_ENABLE                   0x000A
#define WM_SETREDRAW                0x000B
#define WM_SETTEXT                  0x000C
#define WM_GETTEXT                  0x000D
#define WM_GETTEXTLENGTH            0x000E
#define WM_PAINT                    0x000F
#define WM_CLOSE                    0x0010
#define WM_QUERYENDSESSION         0x0011
#define WM_QUIT                     0x0012
#define WM_QUERYOPEN                0x0013
#define WM_ERASEBKGND               0x0014
#define WM_SYSCOLORCHANGE          0x0015
#define WM_ENDSESSION               0x0016
#define WM_SHOWWINDOW               0x0018
#define WM_WININICHANGE             0x001A
#if(WINVER >= 0x0400)
#define WM_SETTINGCHANGE        WM_WININICHANGE
#endif /* WINVER >= 0x0400 */

#define WM_DEVMODECHANGE          0x001B
#define WM_ACTIVATEAPP              0x001C
#define WM_FONTCHANGE               0x001D
#define WM_TIMECHANGE               0x001E
#define WM_CANCELMODE               0x001F
#define WM_SETCURSOR                0x0020
#define WM_MOUSEACTIVATE           0x0021
#define WM_CHILDACTIVATE            0x0022
#define WM_QUEUESYNC                0x0023

#define WM_GETMINMAXINFO            0x0024
// end_r_winuser

// begin_r_winuser
#define WM_PAINTICON             0x0026
#define WM_ICONERASEBKGND      0x0027
#define WM_NEXTDLGCTL               0x0028
#define WM_SPOOLERSTATUS           0x002A
#define WM_DRAWITEM                 0x002B
#define WM_MEASUREITEM              0x002C
#define WM_DELETEITEM               0x002D
#define WM_VKEYTOITEM               0x002E
#define WM_CHARTOITEM               0x002F
#define WM_SETFONT                  0x0030
#define WM_GETFONT                  0x0031
#define WM_SETHOTKEY                0x0032
#define WM_GETHOTKEY                0x0033
#define WM_QUERYDRAGICON            0x0037
#define WM_COMPAREITEM              0x0039
#if(WINVER >= 0x0500)
#define WM_GETOBJECT             0x003D
#endif /* WINVER >= 0x0500 */
#define WM_COMPACTING            0x0041
#define WM_COMMNOTIFY             0x0044  /* no longer suported */
#define WM_WINDOWPOSCHANGING   0x0046
#define WM_WINDOWPOSCHANGED    0x0047

#define WM_POWER                 0x0048
/*
* wParam for WM_POWER window message and DRV_POWER driver notification
*/
#define PWR_OK                   1
#define PWR_FAIL                 (-1)
#define PWR_SUSPENDREQUEST      1
#define PWR_SUSPENDRESUME       2
#define PWR_CRITICALRESUME       3

#define WM_COPYDATA              0x004A
#define WM_CANCELJOURNAL         0x004B
// end_r_winuser

// begin_r_winuser
#if(WINVER >= 0x0400)
#define WM_NOTIFY                0x004E
#define WM_INPUTLANGCHANGEREQUEST  0x0050
#define WM_INPUTLANGCHANGE      0x0051
#define WM_TCARD                    0x0052
#define WM_HELP                     0x0053
#define WM_USERCHANGED            0x0054
#define WM_NOTIFYFORMAT           0x0055

#define NFR_ANSI                    1
#define NFR_UNICODE                 2
#define NF_QUERY                    3
#define NF_REQUERY                  4

#define WM_CONTEXTMENU              0x007B
#define WM_STYLECHANGING            0x007C
#define WM_STYLECHANGED             0x007D
#define WM_DISPLAYCHANGE            0x007E
#define WM_GETICON                  0x007F
#define WM_SETICON                  0x0080
#endif /* WINVER >= 0x0400 */

#define WM_NCCREATE                 0x0081
#define WM_NCDESTROY               0x0082
#define WM_NCCALCSIZE              0x0083
#define WM_NCHITTEST                0x0084
#define WM_NCPAINT                  0x0085
#define WM_NCACTIVATE              0x0086
#define WM_GETDLGCODE             0x0087
#define WM_SYNCPAINT                0x0088
#define WM_NCMOUSEMOVE          0x00A0
#define WM_NCLBUTTONDOWN       0x00A1
#define WM_NCLBUTTONUP           0x00A2
#define WM_NCLBUTTONDBLCLK          0x00A3
#define WM_NCRBUTTONDOWN            0x00A4
#define WM_NCRBUTTONUP              0x00A5
#define WM_NCRBUTTONDBLCLK    0x00A6
#define WM_NCMBUTTONDOWN      0x00A7
#define WM_NCMBUTTONUP          0x00A8
#define WM_NCMBUTTONDBLCLK    0x00A9

#define WM_KEYFIRST                0x0100
#define WM_KEYDOWN                  0x0100
#define WM_KEYUP                    0x0101
#define WM_CHAR                     0x0102
#define WM_DEADCHAR                 0x0103
#define WM_SYSKEYDOWN              0x0104
#define WM_SYSKEYUP                 0x0105
#define WM_SYSCHAR                  0x0106
#define WM_SYSDEADCHAR             0x0107
#define WM_KEYLAST                  0x0108

#if(WINVER >= 0x0400)
#define WM_IME_STARTCOMPOSITION  0x010D
#define WM_IME_ENDCOMPOSITION      0x010E
#define WM_IME_COMPOSITION          0x010F
#define WM_IME_KEYLAST              0x010F
#endif /* WINVER >= 0x0400 */

#define WM_INITDIALOG               0x0110
#define WM_COMMAND                  0x0111
#define WM_SYSCOMMAND              0x0112
#define WM_TIMER                    0x0113
#define WM_HSCROLL                  0x0114
#define WM_VSCROLL                  0x0115
#define WM_INITMENU                 0x0116
#define WM_INITMENUPOPUP            0x0117
#define WM_MENUSELECT               0x011F
#define WM_MENUCHAR                 0x0120
#define WM_ENTERIDLE                0x0121
#if(WINVER >= 0x0500)
#define WM_MENURBUTTONUP          0x0122
#define WM_MENUDRAG                 0x0123
#define WM_MENUGETOBJECT          0x0124
#define WM_UNINITMENUPOPUP        0x0125
#define WM_MENUCOMMAND            0x0126
#endif /* WINVER >= 0x0500 */

#define WM_CTLCOLORMSGBOX        0x0132
#define WM_CTLCOLOREDIT             0x0133
#define WM_CTLCOLORLISTBOX        0x0134
#define WM_CTLCOLORBTN              0x0135
#define WM_CTLCOLORDLG              0x0136
#define WM_CTLCOLORSCROLLBAR    0x0137
#define WM_CTLCOLORSTATIC          0x0138

#define WM_MOUSEFIRST               0x0200
#define WM_MOUSEMOVE                0x0200
#define WM_LBUTTONDOWN              0x0201
#define WM_LBUTTONUP                0x0202
#define WM_LBUTTONDBLCLK            0x0203
#define WM_RBUTTONDOWN              0x0204
#define WM_RBUTTONUP                0x0205
#define WM_RBUTTONDBLCLK            0x0206
#define WM_MBUTTONDOWN              0x0207
#define WM_MBUTTONUP                0x0208
#define WM_MBUTTONDBLCLK            0x0209

#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
#define WM_MOUSEWHEEL              0x020A
#define WM_MOUSELAST                0x020A
#else
#define WM_MOUSELAST                0x0209
#endif /* if (_WIN32_WINNT < 0x0400) */

#if(_WIN32_WINNT >= 0x0400)
#define WHEEL_DELTA              120     /* Value for rolling one detent */
#endif /* _WIN32_WINNT >= 0x0400 */
#if(_WIN32_WINNT >= 0x0400)
#define WHEEL_PAGESCROLL            (UINT_MAX) /* Scroll one page */
#endif /* _WIN32_WINNT >= 0x0400 */

#define WM_PARENTNOTIFY          0x0210
#define WM_ENTERMENULOOP         0x0211
#define WM_EXITMENULOOP          0x0212

#if(WINVER >= 0x0400)
#define WM_NEXTMENU              0x0213
// end_r_winuser


사업자 정보 표시
가나소프트 | 김용유 | 충남 천안시 동남구 목천읍 서리2길 42-1 | 사업자 등록번호 : 312-33-14797 | TEL : 070-8659-0316 | Mail : yykim@gana-soft.com | 통신판매신고번호 : 12390123호 | 사이버몰의 이용약관 바로가기

1) WideString 
캐스팅 시키는 함수. 아래 방법으로 하시면, A에 wchat_t 형식으로 Hello가 들어갑니다. 

A = WideString("Hello"); 

2) StringToOleStr 
원라는 AnsiString용 함수입니다. char 배열도 사용할 수 있습니다. 

A = StringToOleStr("Hello"); 

3) MultiByteToWideChar 
이 방법을 쓰시면 UTF8 형식으로도 변경할 수 있습니다. UniCode를 사용하는 경우, 이 API를 꼭 이용하셔야 합니다. UTF8을 원하시면 CP_ACP 부분을 CP_UTF8 로 바꾸어 주시면 됩니다. 이 방법은 조금 복잡합니다. 먼저 문자열 길이가 얼마나 나오는지 얻어낸 다음, 그 길이만큼 변수를 잡고, 변환을 다시 시켜야 합니다. 

String            stString = "HELLO"; 
int               itWideSize = MultiByteToWideChar(CP_UTF8, 0, stString.c_str(), stString.Length() + 1, NULL, 0); 
wchar_t           *wcTarget = new wchar_t[itWideSize]; 

MultiByteToWideChar(CP_ACP, 0, stString.c_str(), stString.Length() + 1, wcTarget, itWideSize); 
=========================================================================================================

볼랜드포럼 유영인님 글에서 발췌


사업자 정보 표시
가나소프트 | 김용유 | 충남 천안시 동남구 목천읍 서리2길 42-1 | 사업자 등록번호 : 312-33-14797 | TEL : 070-8659-0316 | Mail : yykim@gana-soft.com | 통신판매신고번호 : 12390123호 | 사이버몰의 이용약관 바로가기

MFC에서 프로젝트를 FormView를 쓰면 화면 전환시에 사용하는 법은 다음과 같이 난 작성한다...

메인폼에 사용자 메시지를 받을 수 있는 함수를 다음과 같이 작성한다..

LRESULT CMainFrame::OnFormChange(WPARAM wParam, LPARAM lParam)
{
// TRACE0(" User Message!!");

// Form Change
CView* pOldActiveView = GetActiveView();
CView* pNewActiveView = (CView*)GetDlgItem(wParam);
if(pNewActiveView==NULL) 
{
switch (wParam)  {
case IDD_LDP_CAL_FORM :
pNewActiveView = (CView*)new CLDPSetupCalView; 
TRACE0(" Menu Cal Form Change!!");
break;
case IDD_LDP_MAIN_FORM :
pNewActiveView = (CView*)new CLDPSetupMainView;
TRACE0(" Menu Cal MainChange!!");
break;
}
CCreateContext context;  
context.m_pCurrentDoc=pOldActiveView->GetDocument() ;
pNewActiveView->Create(NULL,NULL,0L,CFrameWnd::rectDefault,this,wParam,&context) ;
pNewActiveView->OnInitialUpdate() ;
}
SetActiveView(pNewActiveView) ;
pNewActiveView->ShowWindow(SW_SHOW) ;
if    (pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CLDPSetupCalView))      
pOldActiveView->SetDlgCtrlID(IDD_LDP_CAL_FORM);
else if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CLDPSetupMainView)) 
pOldActiveView->SetDlgCtrlID(IDD_LDP_MAIN_FORM);
pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST) ;
RecalcLayout();
delete pOldActiveView;
CurrentForm = wParam;

return 0;
}



이런식의 함수를 사용하고자 하는 곳에서...

::SendMessage(AfxGetMainWnd()->m_hWnd, UM_MENUCHANGE, IDD_LDP_CAL_FORM, NULL); 

이런식으로 호출해서 폼이 바뀌는방식을 주로 쓴다..


그리고 C++ 빌더에서는 다음과 같이 사용한다...
1. 이전 화면이 있으면 삭제..
2. 화면 호출 및 생성
3. 화면 크기를 메인폼에 맞게 수정..(Resize 함수 이용)

// 그려질 폼이 메인폼에 맞게 사이즈를 맞추어 준다...

void __fastcall TMainForm::FormResize(TObject *Sender)

{

if(Frame_User){

Frame_User->Width = ClientWidth;

Frame_User->Height = ClientHeight;

return;

}

else if(Frame_Group)

{

Frame_Group->Width = ClientWidth;

Frame_Group->Height = ClientHeight;

}

}


// 기존의 폼을 제거한다..


int __fastcall TMainForm::DeleteFrame()

{

// 사용자 등록 화면 삭제.

if(Frame_User){

delete Frame_User;

Frame_User = NULL;

}

//...//

}



// 그리고 호출 및 생성은...

void __fastcall TMainForm::N2Click(TObject *Sender)

{ // 사용자 등록

DeleteFrame();  // 호출되어 있는 폼 삭제

Frame_User = new TFrame_User(this); // 현재 폼을 오너로 해서 생성

TRect rect = Rect(0,0, ClientWidth, ClientHeight); // 현재 폼을 전체 덮는 크기로 설정

Frame_User->Dock(this, rect); // 현재 폼을 도킹 시켜 보이게 한다..


다음과 같이 처리한다... 어떤 방식이 더 낫다고 볼 수 없다..


김용유닷컴(kimyongyu.com) 예전글에서 발췌 수정

사업자 정보 표시
가나소프트 | 김용유 | 충남 천안시 동남구 목천읍 서리2길 42-1 | 사업자 등록번호 : 312-33-14797 | TEL : 070-8659-0316 | Mail : yykim@gana-soft.com | 통신판매신고번호 : 12390123호 | 사이버몰의 이용약관 바로가기

**********************************************************/

/*                                                        */

/*          Test program for Communication functions      */

/*                                                        */

/*  Copyright (C) 1999 MITSUBISHI Electric Corporation    */

/*  All Rights Reserved                                   */

/**********************************************************/

/********************************************

* Include files *

********************************************/

#include        <stdio.h>

#include        <winsock.h>


#define FLAG_OFF  0 // 종료 플래그 OFF

#define FLAG_ON  1 // 종료 플래그 ON

#define SOCK_OK  0 // 정상 종료 

#define SOCK_NG -1 // 이상 종료 

#define BUF_SIZE 80 // 버퍼 사이즈 


#define ERROR_INITIAL  0 // 초기화 에러 

#define ERROR_SOCKET  1 // 소켓 작성 에러 

#define ERROR_BIND  2 // 바인드 에러

#define ERROR_CONNECT  3 // 커넥트 에러

#define ERROR_SEND  4 // 송신 에러 

#define ERROR_RECEIVE  5 // 수신 에러 

#define ERROR_SHUTDOWN  6 // 셧다운 에러 

#define ERROR_CLOSE  7 // 회선 클로즈 에러 


typedef struct sck_inf {

struct in_addr my_addr;

unsigned short my_port;

struct in_addr aj_addr;

unsigned short aj_port;

};


int nErrorStatus; // 에러 정보 저장 변수

int Dmykeyin; // 더미 키 입력

int Closeflag; // 커넥션 종료 플래그

int socketno;


/***************************************************

* Reads in device "D" of specified No              *

* on station No 1                                  *

***************************************************/

int main()

{

WORD wVersionRequested = MAKEWORD(1,1);  

WSADATA wsaData; // Winsock Ver 1.1 요구 

int length; // 교신 데이터 길이 

int result;

unsigned char s_buf[BUF_SIZE]; // 송신 버퍼 

unsigned char r_buf[BUF_SIZE]; // 수신 버퍼 

struct sck_inf sc; // 구조체 변수 선언

struct sockaddr_in hostdata; // 상대 기기측 데이터

struct sockaddr_in aj71e71; // Ethernet 모듈측 데이터 

void Sockerror(int); // 에러 처리 함수 

sc.my_addr.s_addr = htonl(INADDR_ANY); // 상대 기기측 IP Address(PC쪽 IP Address)

sc.my_port = htons(0); // 상대 기기측 Port No.(PC쪽 Port No.)

sc.aj_addr.s_addr = inet_addr("192.168.16.232"); // Ethernet 모듈측 IP Address(C00001FD) - PLC 모듈 IP 셋팅

sc.aj_port = htons(5002); // Ethernet 모듈측 Port No. - PLC 모듈 

// PLC Port No : 138A(16진수)로 셋팅


Closeflag = FLAG_OFF; // 커넥션 종료 플래그 OFF


nErrorStatus = WSAStartup(wVersionRequested, &wsaData);

if (nErrorStatus != SOCK_OK) // Winsock 초기화 처리

{

Sockerror(ERROR_INITIAL);

return(SOCK_NG);

}


printf("Winsock Version is %d, %d\n", HIBYTE(wsaData.wVersion), LOBYTE(wsaData.wVersion));

printf("AJ_test Start\n");


socketno = socket(AF_INET, SOCK_STREAM, 0); // 소켓 생성

if (socketno == INVALID_SOCKET) // TCP/IP의 소켓 작성 

{

Sockerror(ERROR_SOCKET);

return(SOCK_NG);

}

hostdata.sin_family = AF_INET; // PC 쪽 Socket 구조체 정의 

hostdata.sin_port = sc.my_port; // PC 쪽 Port No, IP Address

hostdata.sin_addr.s_addr = sc.my_addr.s_addr;


if (bind(socketno, (LPSOCKADDR)&hostdata, sizeof(hostdata)) != SOCK_OK) // 바인드

{

Sockerror(ERROR_BIND);

return(SOCK_NG);

}


aj71e71.sin_family = AF_INET; // PLC 쪽 Socket 구조체 정의 

aj71e71.sin_port = sc.aj_port; // PLC 쪽 Port No, IP Address

aj71e71.sin_addr.s_addr = sc.aj_addr.s_addr;

// --------------- 커넥트(Active 오픈 요구) ---------------- //

result = connect(socketno, (LPSOCKADDR)&aj71e71, sizeof(aj71e71));


/*if (connect(socketno, (LPSOCKADDR)&aj71e71, sizeof(aj71e71)) != SOCK_OK)

{

Sockerror(ERROR_CONNECT);

return(SOCK_NG);

printf("AJ_test Start4\n");

}*/


if (result == 0)

{

printf("Connect OK\n");

}

else if (result == SOCKET_ERROR)

{

printf("Connect FAIL\n");

}


Closeflag = FLAG_ON; // 커넥션 종료 플래그 ON


// ----------------이 부분까지 Ethernet과 PLC 연결 부분 ----------------- //


// --------------- D0 ~ D4 일괄 쓰기 요구 ----------------- //

// 송신 데이터를 보내면 " 수신할 수 없습니다, 에러 코드는 0입니다 " 라는 

// 메세지가 나옴 

///*

strcpy(s_buf, "500000FF03FF00002C000A14010000D*0000000005112233445566778899AA");


length = strlen(s_buf);

if (send(socketno, s_buf, length, 0) == SOCKET_ERROR) // 데이터 송신 

{

Sockerror(ERROR_SEND);

return(SOCK_NG);

}

printf("\n 송신 데이터 \n%s\n", s_buf);


length = recv(socketno, r_buf, BUF_SIZE, 0); // 응답 데이터 수신 


if (length = SOCKET_ERROR)

{

Sockerror(ERROR_RECEIVE);

return(SOCK_NG);

}


//r_buf[length] = '\0'; // 수신 데이터 끝에 NULL을 세트


printf("\n 수신 데이터 \n%s\n", r_buf);

//*/

// 위의 부분을 주석 처리후 밑의 읽기 요구는 수신 Data가 들어옴 


// --------------- D0 ~ D4 일괄 읽기 요구 ----------------- //

strcpy(s_buf, "50000FF03FF000018000A04010000D*0000000005");


length = strlen(s_buf);


if (send(socketno, s_buf, length, 0) == SOCKET_ERROR) // 데이터 송신 

{

Sockerror(ERROR_SEND);

return(SOCK_NG);

}


printf("\n 송신 데이터 \n%s\n", s_buf);


length = recv(socketno, r_buf, BUF_SIZE, 0); // 응답 데이터 수신 


if (length == SOCKET_ERROR)

{

Sockerror(ERROR_RECEIVE);

return(SOCK_NG);

}


//r_buf[length] = '\0'; // 수신 데이터의 끝에 NULL을 세트 


printf("\n 수신 데이터 : \n%s\n", r_buf);


if (shutdown(socketno, 2) != SOCK_OK) // 송신 금지 처리 

{

Sockerror(ERROR_SHUTDOWN);

return(SOCK_NG);

}


if (closesocket(socketno) != SOCK_OK)

{

Sockerror(ERROR_CLOSE);

return(SOCK_NG);

}


Closeflag = FLAG_OFF; // 커넥션 종료 플래그 OFF

WSACleanup(); // Winsock.DLL 해제


printf("\nAJ_test End. \n\n 정상 완료했습니다. \n");

printf(" 프로그램을 종료하였습니다, 아무 키나 누르십시오.\n");

Dmykeyin = getchar(); // 키 입력 대기

return(SOCK_OK);

}


void Sockerror(int error_kind) // 에러 처리 함수 

{

if (error_kind == ERROR_INITIAL)

{

printf(" 초기화 처리가 이상합니다.");

}

else

{

nErrorStatus = WSAGetLastError();


switch(error_kind)

{

case ERROR_SOCKET:

printf("소켓을 작성할 수 없습니다.");

break;

case ERROR_BIND:

printf("바인드할 수 없습니다.");

break;

case ERROR_CONNECT:

printf("커넥션을 확립할 수 없습니다.");

break;

case ERROR_SEND:

printf("송신할 수 없습니다.");

break;

case ERROR_RECEIVE:

printf("수신할 수 없습니다.");

break;

case ERROR_SHUTDOWN:

printf("Shutdown할 수 없습니다.");

break;

case ERROR_CLOSE:

printf("정상 클로즈 할 수 없습니다.");

break;

}

}


printf("에러 코드는 %d입니다. \n", nErrorStatus);


if (Closeflag == FLAG_ON)

{

nErrorStatus = shutdown(socketno, 2); // 셧다운 처리 

nErrorStatus = closesocket(socketno); // 클로즈 처리 

Closeflag = FLAG_OFF; // 커넥션 종료 플래그 OFF

}


printf("프로그램을 종료했습니다.아무키나 누르십시오.\n");

Dmykeyin = getchar();

WSACleanup();

return;

}



사업자 정보 표시
가나소프트 | 김용유 | 충남 천안시 동남구 목천읍 서리2길 42-1 | 사업자 등록번호 : 312-33-14797 | TEL : 070-8659-0316 | Mail : yykim@gana-soft.com | 통신판매신고번호 : 12390123호 | 사이버몰의 이용약관 바로가기

+ Recent posts