|
|
Sky_Park Web Content Accessibility Evaluation
Product by SUNMOON BIT 20TH Team 3 |
Contents |
1. Project Team
2. Background
3. Architecture & Evaluation Flow
4. Technology
5. Conclusion
6. Future Work
7. Reference
1. Project Team
1.1 Leader
김 대 근 (2005732009)
1.2 Member
김 윤 환 (2004723015)
블라디미르 (2007242147)
주 은 호 (2003690210)
2. Background
2.1 웹 접근성
장애인, 노인 등 정보 취약계층이 인터넷 상에서 차별
없이 다른 사용자와 동등하게 정보에 접근하고 이해 할
수 있도록 보장하는 것으로 웹 접근성의 주 목적은 웹
콘텐츠를 이용하는 데에 어떠한 상황이나 환경에 구애
받지 않고 접근 할 수 있도록 하는 것 이다.
2.2 웹 접근성 실태
<출처 : 한국 정보화 진흥원 “2009년 4월 웹 접근성 실태조사”>
웹 접근성 인식제고 및 실태파악을 통해 웹 접근성 관련 정책을 수립하기 위해 2005년부터 매년 중앙행정기관, 자치단체, 공공기관 등 을 대상으로 웹 접근성 실태조사를 실시하고 있다.
2010년에는 장애인들이 많이 활용하고 있는 민간기업 50여 개를 포함하여 총 600여 개 사이트를 대상으로 웹 접근성 실태조사를 실시할 예정이며, 조사결과를 바탕으로 웹 접근성 우수 / 위반 사례집을 발간할 계획이라고 한다.
이와 더불어 2009susd는 e-러닝 사이트의 장애인 접근성 제고를 위해 e-러닝 콘텐츠 접근성 개선 추진전략 연구를 수행, 2010년에는 웹 접근성 준수의 필요성 및 모바일 등 새로운 기술 환경에서 장애인이 비장애인과 동등하게 웹을 이용할 수 있도록 기반연구를 수행 할 예정에 있다.
3. Architecture & Evaluation Flow
3.1 Architecture
3.2 Evaluation Flow
4. Technology
4.1 원격제어
1. 원격제어
1.1 Server Class (원격제어를 요청하는 컴퓨터)
Form |
|
구성 |
Server Class, SendEvent Class |
코드 |
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; using System.Net;
namespace Server { public partial class Server : Form { private string IP; private int PORT; private Thread SendImg = null; private Thread MouseEvent = null;
private SendEvent S_Evnt = new SendEvent();
public Server() { InitializeComponent(); }
private void REQButton_Click(object sender, EventArgs e) { if (SendImg == null) { IP = IPTextBox.Text; PORT = int.Parse(PTTextBox.Text);
SetThread(); } else { MessageBox.Show("중지 먼저"); } }
private void SetThread() { S_Evnt.SetEvnt(IP, PORT);
ThreadStart ss = new ThreadStart(S_Evnt.Doit_Img); SendImg = new Thread(ss); SendImg.Start();
ThreadStart sc = new ThreadStart(S_Evnt.Doit_Recv); MouseEvent = new Thread(sc); MouseEvent.Start();
}
private void SButton_Click(object sender, EventArgs e) { if (SendImg != null) { SendImg.Abort(); SendImg = null; } if (MouseEvent != null) { MouseEvent.Abort(); MouseEvent = null; } S_Evnt.Close(); }
private void Server_Load(object sender, EventArgs e) { string hostname = string.Empty;
IPHostEntry ipentry = Dns.GetHostByName(hostname); IPAddress ipaddr = ipentry.AddressList[0];
IPTextBox.Text = ipaddr.ToString(); }
private void Server_FormClosed(object sender, FormClosedEventArgs e) { if (SendImg != null) { SendImg.Abort(); SendImg = null; } if (MouseEvent != null) { MouseEvent.Abort(); MouseEvent = null; } S_Evnt.Close(); } } }
|
Server Class는 클라이언트에 원격제어를 요청하고 이미지와 키보드 및 마우스 이벤트를 동작하기 위한 쓰레드를 생성하고 Start한다. |
1.1.1 SendEvent Class
주요 사용하는 함수 |
-이미지 관련 public void Doit_Img(); private byte[] PacketImg(); private byte[] Cps_Img(byte[] p, MemoryStream screen); private ImageCodecInfo GetEncoder(ImageFormat imageFormat);
-이벤트 관련 public void Doit_Recv(); private void KeyboardInfo(string p, KEYSTATE kEYSTATE); private void MouseInfo(Point point, MOUSESTATE mOUSESTATE);
-API 함수 public static extern void mouse_event(uint dwFlags, uint x, uint y, int state, int info); public static extern void keybd_event(byte Vkey, byte Scan, int dwFlags, int info); static extern bool SetCursorPos(int x, int y); |
전체 코드 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Windows.Forms; using System.Drawing; using System.IO; using System.Drawing.Imaging; using System.Runtime.InteropServices;
namespace Server { class SendEvent { [DllImport("user32.dll")] public static extern void mouse_event(uint dwFlags, uint x, uint y, int state, int info); [DllImport("user32.dll")] public static extern void keybd_event(byte Vkey, byte Scan, int dwFlags, int info);
enum MOUSESTATE { M_LBUP, M_LBDOWN, M_RBUP, M_RBDOWN, M_MOVE }; enum KEYSTATE { KEYUP, KEYDOWN, SHIFTDOWN, SHIFTUP };
private IPAddress IP; private int PORT; private TcpListener tcplistener;
internal void SetEvnt(string _ip, int _port) { IP = IPAddress.Parse(_ip); this.PORT = _port; }
internal void Close() { if(tcplistener != null) { tcplistener.Stop(); tcplistener = null; } }
public void Doit_Recv() { while (true) { if (tcplistener == null) { tcplistener = new TcpListener(IP, PORT); tcplistener.Start(); } try { TcpClient tc = tcplistener.AcceptTcpClient(); NetworkStream ns = tc.GetStream(); if(ns.DataAvailable) { byte[] buf = new byte[1024]; if(ns.Read(buf,0,buf.Length) >0) { string[] recvstr = Encoding.ASCII.GetString(buf).Split(',');
if(recvstr[0] == "M_LBDOWN") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_LBDOWN); } else if(recvstr[0] == "M_RBDOWN") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_RBDOWN); } else if (recvstr[0] == "M_MOVE") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_MOVE); } else if (recvstr[0] == "M_LBUP") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_LBUP); } else if (recvstr[0] == "M_RBUP") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_RBUP); } else if (recvstr[0] == "KeyDown") { KeyboardInfo(recvstr[1], KEYSTATE.KEYDOWN); } else if (recvstr[0] == "KeyUp") { KeyboardInfo(recvstr[1], KEYSTATE.KEYUP); } } } } catch { } } }
private void KeyboardInfo(string p, KEYSTATE kEYSTATE) { const int KEYUP = 0x0002; byte key = (byte)int.Parse(p);
if(kEYSTATE == KEYSTATE.KEYDOWN) { keybd_event(key, 0, 0, 0); } else { keybd_event(key, 0, KEYUP, 0); } }
[DllImport("user32.dll")] static extern bool SetCursorPos(int x, int y);
private void MouseInfo(Point point, MOUSESTATE mOUSESTATE) { const uint MOUSEMOVE = 0x0001; const uint LEFTDOWN = 0x0002; const uint RIGHTDOWN = 0x0008; const uint RIGHTUP = 0x0010; const uint LEFTUP = 0x0004; const uint ABSOLUTEMOVE = 0x8000;
Rectangle rScreen = Screen.PrimaryScreen.Bounds;
switch (mOUSESTATE) { case MOUSESTATE.M_LBDOWN : SetCursorPos(point.X, point.Y ); mouse_event(LEFTDOWN, 0, 0, 0, 0); break; case MOUSESTATE.M_MOVE: SetCursorPos(point.X, point.Y ); mouse_event(MOUSEMOVE, 0, 0, 0, 0); break; case MOUSESTATE.M_RBDOWN: SetCursorPos(point.X, point.Y ); mouse_event(RIGHTDOWN, 0, 0, 0, 0); break; case MOUSESTATE.M_RBUP: SetCursorPos(point.X, point.Y ); mouse_event(RIGHTUP, 0, 0, 0, 0); break; case MOUSESTATE.M_LBUP: SetCursorPos(point.X, point.Y); mouse_event(LEFTUP, 0, 0, 0, 0); break; default : break; } }
public void Doit_Img() { while (true) { if(tcplistener == null) { tcplistener = new TcpListener(IPAddress.Any, PORT); tcplistener.Start(); } try { byte[] image = PacketImg(); SendImg(image); } catch { Close(); } } }
private void SendImg(byte[] image) { TcpClient client = new TcpClient(); client.Connect(IP,PORT); NetworkStream ns = client.GetStream();
ns.Write(image, 0, image.Length); ns.Flush(); client.Close(); }
private byte[] PacketImg()// { int width = Screen.AllScreens[0].Bounds.Width; int height = Screen.AllScreens[0].Bounds.Height;
Size size = new Size(width, height); Bitmap bitmap = new Bitmap(width, height); Graphics gr = Graphics.FromImage(bitmap);
gr.CopyFromScreen(0, 0, 0, 0, size);
MemoryStream ms = new MemoryStream(); bitmap.Save(ms, ImageFormat.Jpeg); ms.Position = 0;
return Cps_Img(ms.ToArray(), ms); }
private byte[] Cps_Img(byte[] p, MemoryStream screen) { Bitmap bm = new Bitmap(screen); ImageCodecInfo jpegEncoder = GetEncoder(ImageFormat.Jpeg);
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality; EncoderParameters myEncoderParameters = new EncoderParameters(1); EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder,60L);
myEncoderParameters.Param[0] = myEncoderParameter; MemoryStream ms = new MemoryStream(); bm.Save(ms, jpegEncoder, myEncoderParameters);
byte[] buf = ms.ToArray(); byte[] pack = new byte[4 + (int)ms.Position];
MemoryStream ms2 = new MemoryStream(pack); BinaryWriter bw = new BinaryWriter(ms2); bw.Write((int)ms.Position); bw.Write(buf, 0, (int)ms.Position); return pack; }
private ImageCodecInfo GetEncoder(ImageFormat imageFormat) { ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); foreach(ImageCodecInfo codec in codecs) { if(codec.FormatID == imageFormat.Guid) { return codec; } } return null; } } } |
전체적 클래스 설명 |
SendEvent Class는 원격제어를 하는 컴퓨터에서 오는 키보드 및 마우스 이벤트를 받아서 실행하는 클래스이다. 해당 클래스에서 Doit_Recv함수는 NetworkStream에서 읽어온 data를 가지고 마우스 이벤트인지 키보드 이벤트인지 구분하여 해당 이벤트를 동작할 함수를 호출한다. 호출되는 함수는 KeyboardInfo 와 MouseInfo이다. Doit_Img 함수에서는 자신의 이미지를 PacketImg로 패킷화 하며 그 과정에서 Cps_Img 라는 함수로 압축하여 보내준다. |
주요 함수 설명 |
public void Doit_Img() { while (true) { if(tcplistener == null) { tcplistener = new TcpListener(IPAddress.Any, PORT); tcplistener.Start(); } try { byte[] image = PacketImg(); SendImg(image); } catch { Close(); } } } |
TcpListener 를 생성하고 Start 시킨다. 이후에는 이미지를 패킷화 하여 보낸다. |
private byte[] PacketImg()// { int width = Screen.AllScreens[0].Bounds.Width; int height = Screen.AllScreens[0].Bounds.Height;
Size size = new Size(width, height); Bitmap bitmap = new Bitmap(width, height); Graphics gr = Graphics.FromImage(bitmap);
gr.CopyFromScreen(0, 0, 0, 0, size);
MemoryStream ms = new MemoryStream(); bitmap.Save(ms, ImageFormat.Jpeg); ms.Position = 0;
return Cps_Img(ms.ToArray(), ms); } |
이미지의 사이즈를 측정하고 해당 사이즈에 맞게 이미지 개체를 만들고 압축할 준비를 한다. |
private byte[] Cps_Img(byte[] p, MemoryStream screen) { Bitmap bm = new Bitmap(screen); ImageCodecInfo jpegEncoder = GetEncoder(ImageFormat.Jpeg);
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality; EncoderParameters myEncoderParameters = new EncoderParameters(1); EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder,60L);
myEncoderParameters.Param[0] = myEncoderParameter; MemoryStream ms = new MemoryStream(); bm.Save(ms, jpegEncoder, myEncoderParameters);
byte[] buf = ms.ToArray(); byte[] pack = new byte[4 + (int)ms.Position];
MemoryStream ms2 = new MemoryStream(pack); BinaryWriter bw = new BinaryWriter(ms2); bw.Write((int)ms.Position); bw.Write(buf, 0, (int)ms.Position); return pack; }
|
이미지를 패킷화 해서 보내기 전에 압축을 한다. 코드에 60L 이라는 부분은 이미지의 품질 상태를 선택하는 것이다. 나머지는 기존의 소켓 통신과 같다. |
private ImageCodecInfo GetEncoder(ImageFormat imageFormat) { ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); foreach(ImageCodecInfo codec in codecs) { if(codec.FormatID == imageFormat.Guid) { return codec; } } return null; }
|
이미지를 실질적으로 압축하는 코드이다. |
public void Doit_Recv() { while (true) { if (tcplistener == null) { tcplistener = new TcpListener(IP, PORT); tcplistener.Start(); } try { TcpClient tc = tcplistener.AcceptTcpClient(); NetworkStream ns = tc.GetStream(); if(ns.DataAvailable) { byte[] buf = new byte[1024]; if(ns.Read(buf,0,buf.Length) >0) { string[] recvstr = Encoding.ASCII.GetString(buf).Split(',');
if(recvstr[0] == "M_LBDOWN") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_LBDOWN); } else if(recvstr[0] == "M_RBDOWN") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_RBDOWN); } else if (recvstr[0] == "M_MOVE") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_MOVE); } else if (recvstr[0] == "M_LBUP") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_LBUP); } else if (recvstr[0] == "M_RBUP") { MouseInfo(new Point(int.Parse(recvstr[1]), int.Parse(recvstr[2])), MOUSESTATE.M_RBUP); } else if (recvstr[0] == "KeyDown") { KeyboardInfo(recvstr[1], KEYSTATE.KEYDOWN); } else if (recvstr[0] == "KeyUp") { KeyboardInfo(recvstr[1], KEYSTATE.KEYUP); } } } } catch { } } }
|
이벤트를 받아서 받은 이벤트가 어떤건지 if문으로 제어한다. |
private void KeyboardInfo(string p, KEYSTATE kEYSTATE); private void MouseInfo(Point point, MOUSESTATE mOUSESTATE); |
위의 두 함수는 코드가 비슷하며, API함수를 불러와 사용하는 용도로만 사용된다. |
-API 함수 public static extern void mouse_event(uint dwFlags, uint x, uint y, int state, int info); public static extern void keybd_event(byte Vkey, byte Scan, int dwFlags, int info); static extern bool SetCursorPos(int x, int y); |
각각의 API 함수들은 실제 API 함수내에서 동작하는 행동과 똑같이 동작한다. |
1.2 Client Class
Form |
|
구성 |
Client Class, MouseEvnet Class, RecvImg Class, tcp Class |
주요 사용 함수 |
-이벤트 private void Event(MOUSESTATE mOUSESTATE);
-이미지 public void DoitRecv();
-tcplistenerr static public TcpListener SetTcp(IPAddress _ip, int _port) |
전체 코드 |
Client |
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Net.Sockets; using System.Threading; using System.Net;
namespace Client { public partial class Client : Form { private Thread recvThread = null; private MouseEvent me; private RecvImg recv;
public Client() { InitializeComponent(); me = new MouseEvent();
}
private void OButton_Click(object sender, EventArgs e) { if (recvThread == null) { IPAddress ip = IPAddress.Parse(IP.Text);
recv = new RecvImg(ip, int.Parse(PORT.Text), PB, label1); recv.ServerXYEventHadler += new RecvImg.ServerXY(recv_ServerXYEventHadler);
ThreadStart start = new ThreadStart(recv.DoitRecv); recvThread = new Thread(start); recvThread.IsBackground = true; recvThread.Start();
me.SetTcpListener(ip, int.Parse(PORT.Text));
} else { MessageBox.Show("중지 먼저"); } }
public int server_x; public int server_y; void recv_ServerXYEventHadler(int _x, int _y) { server_x = _x; server_y = _y; }
private void NButton_Click(object sender, EventArgs e) { recvThread.Abort(); this.Close(); }
private void Client_FormClosed(object sender, FormClosedEventArgs e) { if (recvThread != null) { recvThread.Abort(); recvThread = null; } }
private void Client_Load(object sender, EventArgs e) {
}
private void PB_MouseDown(object sender, MouseEventArgs e) { me.SetMouseDown(e,PB.Width,PB.Height,server_x,server_y);
}
private void PB_MouseMove(object sender, MouseEventArgs e) { me.SetMousePoint(e,label1); }
private void PB_MouseUp(object sender, MouseEventArgs e) { me.SetMouseUp(e, PB.Width, PB.Height, server_x, server_y);
}
private void IP_TextChanged(object sender, EventArgs e) {
}
private void Client_KeyDown(object sender, KeyEventArgs e) { me.SetKeyDown(e); }
private void Client_KeyUp(object sender, KeyEventArgs e) { me.SetKeyUp(e); }
private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e) {
}
private void IP_KeyDown(object sender, KeyEventArgs e) { me.SetKeyDown(e); }
private void IP_KeyUp(object sender, KeyEventArgs e) { me.SetKeyUp(e); } private void PB_Click(object sender, EventArgs e) { this.Focus(); }
private void PORT_TextChanged(object sender, EventArgs e) { //me.SetKeyDown(e); }
private void PORT_KeyDown(object sender, KeyEventArgs e) { me.SetKeyDown(e); } } }
|
Client Class는 원격제어를 수락하는 클래스로 Server에서 요청이 오면 원격제어를 수락하여 요청이 온 컴퓨터를 제어한다. 마우스와 키보드 이벤트들은 MouseEvent Class로 보내고 이미지는 RecvImg Class에서 받는다. 해당코드는 모두 이벤트 함수에서 MouseEvent 함수를 호출 하는 일밖에 안한다. |
private void Event(MOUSESTATE mOUSESTATE) { string send_mouse = string.Empty;
if(mOUSESTATE == MOUSESTATE.M_LBDOWN) { send_mouse = "M_LBDOWN" + "," + (m_point.X * server_x / client_x).ToString() + "," + (m_point.Y * server_y / client_y).ToString() + ","; SendMouseEvent(send_mouse); } if (mOUSESTATE == MOUSESTATE.M_RBDOWN) { send_mouse = "M_RBDOWN" + "," + (m_point.X * server_x / client_x).ToString() + "," + (m_point.Y * server_y / client_y).ToString() + ","; SendMouseEvent(send_mouse); } if(mOUSESTATE == MOUSESTATE.M_MOVE) {
} if (mOUSESTATE == MOUSESTATE.M_LBUP) { send_mouse = "M_LBUP" + "," + (m_point.X * server_x / client_x).ToString() + "," + (m_point.Y * server_y / client_y).ToString() + ","; SendMouseEvent(send_mouse); } if (mOUSESTATE == MOUSESTATE.M_RBUP) { send_mouse = "M_RBUP" + "," + (m_point.X * server_x / client_x).ToString() + "," + (m_point.Y * server_y / client_y).ToString() + ","; SendMouseEvent(send_mouse); } } |
Event 함수는 선택된 이벤트에 해당하는 string형 문장을 만들어 전송한다. |
public void DoitRecv() {
string hostname = string.Empty; IPHostEntry ipentry = Dns.GetHostByName(hostname); IPAddress ipaddr = ipentry.AddressList[0];
tcplistner = tcp.SetTcp(ipaddr, PORT); while (true) { TcpClient tc = tcplistner.AcceptTcpClient(); NetworkStream stream = tc.GetStream(); BinaryReader br = new BinaryReader(stream); int len = br.ReadInt32();
if (stream.DataAvailable) { byte[] mybuf = new byte[1024];//임시버퍼 byte[] bitmap = new byte[len];
int numberOfBytesRead = 0;//읽은 사이즈
int start = 0; while (start < len) { numberOfBytesRead = stream.Read(mybuf, 0, mybuf.Length); if (numberOfBytesRead == 0) { break; } Array.Copy(mybuf, 0, bitmap, start, numberOfBytesRead); start += numberOfBytesRead; } MemoryStream ms = new MemoryStream(); ms.Write(bitmap, 0, bitmap.Length); Bitmap bmap = new Bitmap(ms);
server_width = bmap.Width; server_height = bmap.Height; ServerXYEventHadler(server_width, server_height);
pic.Image = bmap; } } tcplistner.Stop(); } |
이미지를 Server 로부터 받아오게 되면 Picture Box에 등록한다. 받아오는 과정은 위의 코드를 보면 알 수 있다. |
static public TcpListener SetTcp(IPAddress _ip, int _port) { IP = _ip; PORT = _port; tcplistener = new TcpListener(IP, PORT); tcplistener.Start(); return tcplistener; } |
TcpListener 해당 개체를 하나만 만들기 위하여 static한 클래스에서 해당 개체를 생성하고 Start 했다. |
1.3 UserControl – 자동
Form (ex 1.1.1 <Img>요소에 대체 텍스트가 존재하지 않습니다. |
|
구성 |
User1111, TestCase |
public partial class User1111 : UserControl { public HtmlElement He { get; private set; } Pasing에서 얻어낸 HtmlElement개체 저장 public int Line { get; set; } 전체 HTML문서에의 위치 저장 public string OutHtml { get; set; } Pasing에서 얻어낸 HTML코드 저장 public User1111() { InitializeComponent(); } public User1111(HtmlElement _he) { InitializeComponent(); He = _he; OutHtml = He.OuterHtml; } 사용자 지정컨트롤 생성자 public string GetOuterHtml() { return He.OuterHtml; } public override string ToString() { return He.OuterHtml; } public delegate void SetUserTag(string ho,User1111 user1111); public event SetUserTag SetUserTagEventhandler; Html문서 수정을 위한 EventHandler private void button1_Click(object sender, EventArgs e) { string ho = He.OuterHtml; int strlen = textBox1.Text.Length; if (strlen > 255) { He.SetAttribute("longdesc", textBox1.Text); MessageBox.Show("alt 요소가 255 자 이상 입력하여 longdesc 요소로 입력이 되었습니다."); } else { He.SetAttribute("alt", textBox1.Text); } OutHtml = He.OuterHtml; SetUserTagEventhandler.Invoke(ho, this); } internal void SetLine(int cnt) { Line = cnt; } } |
해당 UserControl 검사 Class |
HtmlDocument hdoc; 브라우저의 HTML문서를 나타내는 HtmlDocument 개체 생성 HtmlElementCollection helcols; HtmlElement 개체의 컬렉션을 정의하는 HtmlElementCollection개체 생성 if(hdoc != null) { helcols = hdoc.All; HTML 문서 전체를 컬렉션으로 얻어온다. foreach (HtmlElement he in helcols) { if (he.TagName.ToUpper() == "IMG" || he.TagName.ToUpper() == "IMAGE") HTML 태그 이름이 IMG / IMAGE인 HTML코드를 선별한다. { if (he.GetAttribute("alt") == string.Empty || he.GetAttribute("longdesc") == string.Empty) IMG / IMAGE 안에 alt / longdesc속성이 없거나 / 그 값이 존재하지 않는 HTML코드를 선별한다. { User1111 user1111 = new User1111(he); 테스트 케이스별로 사용자 지정 컨트롤을 생성한다. user1111.SetUserTagEventhandler += new User1111.SetUserTag(user1111_SetUserTagEventhandler); TreeNode str = new TreeNode(user1111.ToString()); tr.Nodes.Add(str); if(!udic.ContainsKey(user1111.ToString())) { udic.Add(user1111.ToString(),user1111); } } } } } |
1.4 UserControl – 반자동
|
UI |
public User2111() { InitializeComponent(); } public User2111(HtmlElement _he) { InitializeComponent(); He = _he; OutHtml = He.OuterHtml; }
|
생성자 |
public HtmlElement He Pasing에서 얻어낸 HtmlElement개체 저장 { get; private set; } public int Line 전체 HTML문서에의 위치 저장 { get; set; } public string OutHtml Pasing에서 얻어낸 HTML코드 저장 { get; set; } public string GetOuterHtml() { return He.OuterHtml; } public override string ToString() { return He.OuterHtml; } internal void SetLine(int cnt) { Line = cnt; } |
기타 |
private void prevBt_Click(object sender, EventArgs e) 이전 버튼 클릭시 SummaryTextBox내용 저장 및 체크박스 체크상태 저장. { Summary = Summarytxt.Text; BCheck = BadCheck.Checked; GCheck = GoodCheck.Checked; } |
이전 버튼 클릭 이벤트 |
private void nextBt_Click(object sender, EventArgs e) 다음 버튼 클릭시 SummaryTextBox내용 저장 및 체크박스 체크상태 저장. { Summary = Summarytxt.Text; BCheck = BadCheck.Checked; GCheck = GoodCheck.Checked; } |
다음 버튼 클릭 이벤트 |
private void GoodCheck_CheckedChanged(object sender, EventArgs e) 잘된 체크 상태가 변할 시 발생 { if (GoodCheck.Checked == true) { BadCheck.Checked = false; } if (GoodCheck.Checked == false) { BadCheck.Checked = true; } } private void BadCheck_CheckedChanged(object sender, EventArgs e) 안된 체크 상태가 변할 시 발생 { if (BadCheck.Checked == true) { GoodCheck.Checked = false; } if (BadCheck.Checked == false) { GoodCheck.Checked = true; } } |
체크 박스 체크 상태 변경시 발생 이벤트 |
첨부(위와 비슷한 UserControl : 총 23개)
1.1.1 텍스트가 아닌 콘텐츠 |
<area> 요소에 대체 텍스트가 존재하지 않습니다. |
1.1.1 텍스트가 아닌 콘텐츠 |
<input type=”image” > 요소에 대체 텍스트가 존재하지 않습니다. |
1.1.1 텍스트가 아닌 콘텐츠 |
<applet> 요소에 대체 텍스트가 존재하지 않습니다. |
1.1.1 텍스트가 아닌 콘텐츠 |
대체 텍스트가 너무 깁니다. |
1.1.1 텍스트가 아닌 콘텐츠 |
대체 텍스트 내용이 올바른지 확인하십시오 |
1.1.1 텍스트가 아닌 콘텐츠 |
플래시 콘텐츠의 대체 텍스트가 제공되었는지 확인하십시오 |
3.3.1 오류 식별 |
입력된 값을 체크하여 사용자에게 오류내용을 제공하십시오 |
4.1.1 파싱 |
DOCTYPE을 명시해야한다. |
1.2.1/ 1.4.1 / 1.4.3 오디오 전용 |
미디어 파일에 대한 링크가 발견되지 않았습니다. 대체 수단을 제공하십시오. |
2.1.1.1 키보드 인터페이스 |
서버측 이미지맵을 제공하는 ismap 속성이 발견되었습니다 |
2.1.1.2 키보드 인터페이스 |
서버측 이미지 맵에 대한 대체 콘텐츠가 없습니다 |
2.1.1.3 키보드 인터페이스 |
플래시 콘텐츠의 임베딩 방법을 확인하십시오 |
2.1.1.4 키보드 인터페이스 |
마우스 이벤트에 대한 키보드 이벤트가 존재하지 않습니다 |
2.2.1.1 타이밍 조절기능 |
요소내에 자동으로 새로 고치는 기능이 포함되어 있습니다 |
2.2.1.2 타이밍 조절기능 |
자바 스크립트 내에 setTimeout, setInterval함수를 사용하여 시간제한을 하지 마십시오 |
2.3.1 깜빡이는 gif |
세번 깜박임이나 기준점 아래- 움직이는 gif이미지가 발견되었습니다 |
2.4.2.1 페이지 제목 |
문서에 제목이 없습니다 |
2.4.6 해딩 및 레이블(Headings and Labels) |
문서 구조를 표현 하려면 <h1/>…<h6/> 요소를 사용 해야 한다 |
2.4.7 보이는 초점 |
[안내]태그제한으로등록되지않습니다-xx[안내]태그제한으로등록되지않습니다-xxonfocus=”this.blur()” 사용으로 포커스가 불가능합니다 |
2.4.10 섹션 헤딩(Section Headings) |
정보가 많은 온라인 서식은 이해하기 쉽도록 그룹으로 묶어 사용 해야 한다 |
2.4.11 섹션 헤딩(Section Headings)- |
선택 항목이 많을 경우 <optgroup> 요소를 사용하여 그룹화 해야 한다 |
2.4.21 문서 제목 |
문서 제목이 제공되지 않았습니다. |
3.3.11 오류 식별(Error Identification) |
입력된 값을 체크하여 사용자에게 오류내용을 제공하십시오 |
4.2 Report Viewer
4.2. 1 ReportViewerControl
Microsoft visualstudio2008 에는 사용자 지정 응용프로그램에 전체 기능을 갖춘 보고서를 추가할 수 있도록 보고서 디자인 기능과, ReportViewer 컨트롤이 있습니다.
보고서는 테이블형식, 집계 및 다차원 데이터를 포함할 수 있다.
ReportviewerWindowsForms 컨트롤은 Windows 응용 프로그램 프로젝트에 보고서를 호스팅하는 데 사용된다.
Reportviewer웹 서버 컨트롤은 ASP.NET 프로젝트에 보고서를 호스팅하는 데 사용된다.
로컬 처리 모드는 클라이언트 응용 프로그램에서 Reportviewer 컨트롤이 수행하는 보고서 처리다.
원격 처리모드는SQL Server2005 Reporting Services 보고서 서버에서 수행하는 보고서 처리를 말한다.
1) Database와 기본적인 연결 및 테이블 작성
3) 페이지 값을 설정하여 도구상자의 ‘목록’ 도구 설정
2.1 보고서 마법사를 통하여 작성
보고서 마법사의 테이블 디자인
페이지 사항에 원하는 필드 항목을 넣은 후 나머지 필드를 입력.
2.2 수동으로 작성
보고서 형식의 새 항목을 추가한다.
새로 생성한 보고서에 ‘목록’ 도구상자를 추가한다.
목록 도구상자 속성에서 데이터 집합 이름을 선택하여 준다.
그룹화할 대상의 식을 입력해준다.
목록 내에 테이블 생성시 테이블 집합 이름을 설정해준 후
사용할 필드의 그룹 목록을 추가하여 주어야 한다.
테이블에 필드값을 입력하여 테이블을 완성한다.
4)Sub-Report
보고서 내의 포함된 보고서는 보고서 자체에서 매개변수를 넘겨주어 포함된 보고서 내에서는 해당 매개변수를 받아 이를 참고하여 보고서의 내용을 완성하는 보고서 형식을 제공한다. 보고서 매개변수는 조건부 서식을 지원하거나 식 또는 코드에서사용할 매개변수를 정의한다.
보고서 매개변수 대화상자에서 지정한 매개변수 속성은 보고서 정의에 포함된다.
기술 문서의 내용에서는 다음과 같은 포함된 보고서를 정의하는 작업을 하게 된다.
Mainreport.rdlc
Detail-subreport.rdlc
Mainreport.rdlc Detail-subreport.rdlc
Mainreport. 에서 쓰이는 데이터 소스 와 Detail-subreport에서 쓰이는 데이터 소스의 내용이다.
해당 소스들은 실제적으로 관계는 전혀 없다.
하지만
Detail-subreport 의 매개변수를 하나 설정하고(String 형을 받는 Guideparam).
Mainreport에 있는 포함된 보고서 컨트롤의 매개변수 속성을 설정해준다.
(매개변수 이름 탭에 있는 빈칸을 누르면 Detail-subreport에서 설정한 매개변수 목록이 보이며, 이를 설정하고 매개변수 값을 입력하면 된다.)
그럼 Mainreport에 있는 Guide필드의 값이 매개변수로 넘어가게 된다.
이후 Detail-subreport의 테이블속성의 Guide필드의 필터 값으로 정의한 매개변수로 설정하게 되면 해당 테이블은 Guideparam의 매개변수로 넘어오는 값을 Guide필드값으로 대입하여 테이블을 작성 하게된다.
5. Conclusion
5.1 구상한 UI만큼의 Output이 나오지 않았다
정해진 시간 안에 익힐 수 있는 기술력에 한계가 있었다.
5.2 웹 접근성 평가에 도움이 되는 프로그램이다.
구상한 정도의 Output은 나오지 않았지만, 웹 접근성
평가에 도움이 되는 프로그램이다.
6. Future Work
6.1 WCAG의 변화에 따른 가용성이 있어야 한다.
6.2 더 많은 format의 report를 제공해야 한다.
6.3 수동 검색을 지원해주는 더 많은 환경을 제공해야 한다.
7. Reference
7.1 WordWideWeb Consortium website
7.2 Microsoft Msdn website
7.3 Html tutorial website http://www.3schools.com/html/default.asp
7.4 C# tutorial website
|