Recently, the National Immigration Administration has upgraded and facilitated the application of foreign permanent residence identity cards (hereinafter referred to as permanent residence certificates). The new version of the permanent residence certificate will be officially issued on December 1, 2023. The new version of the permanent residence permit has adjusted the numbering rules and improved the information
information storage, optimized pattern design, and clarified matters for convenient application in the civil aviation field. In addition, after the issuance of the new version of the permanent residence permit is officially launched, the issuance of the 2017 version of the permanent residence permit will be stopped. The previous versions of the permanent residence permit (including the permanent residence permit for foreigners and the 2017 version of the permanent residence permit) can still be used normally during their validity period. After reaching the expiration date, a new permanent residence permit must be issued.
According to relevant document requirements, the interface of the ID card reader must be updated to achieve reading compatibility with the new version of the permanent residence permit for foreigners.
C++ reads the rendering of the new version of the permanent residence permit for foreigners:
The following is the C++ implementation code:
void CDonseeTestDlg::OnBnClickedButton19() { { m_bPhoto = FALSE; CRect r; HDC hDC; HPEN hPen, hPenOld; HBRUSH hBrush, hBrushOld; hDC = ::GetDC(m_Static_Photo.m_hWnd); m_Static_Photo.GetClientRect( & amp;r); hPen = CreatePen(PS_NULL, 0, GetSysColor(COLOR_3DFACE)); // without black borders hPenOld = (HPEN)SelectObject(hDC, hPen); hBrush = GetSysColorBrush(COLOR_3DFACE); hBrushOld = (HBRUSH)SelectObject(hDC, hBrush); Rectangle(hDC, r.left + 1, r.top + 1, r.right-1, r.bottom-1); SelectObject(hDC, hBrushOld); SelectObject(hDC, hPenOld); ::ReleaseDC(m_Static_Photo.m_hWnd, hDC); } CWnd *pWnd; pWnd = GetDlgItem(IDC_STATIC_PHOTO); // pWnd->GetWindowRect(m_rtPicShow); // ScreenToClient(m_rtPicShow); m_bPhoto = FALSE; if ((m_isOpenUSB == false) & amp; & amp; (m_isOpenCOM == false)) { InsertInfo(L"EST-100 ID card reader connection failed, please open the USB or COM port first"); return ; } char t_arrMsg[256]; char t_szPicPath[256] = "IDphoto.jpg"; CString t_strTemp; IDINFO idInfo; memset( & idInfo,0,sizeof(IDINFO)) ; int t_nType = m_Combo5.GetCurSel(); long t_nRe = Donsee_ReadIDCard(t_nType,t_szPicPath, & idInfo,t_arrMsg); if (t_nRe != 0 ) { t_strTemp = t_arrMsg; InsertInfo(L"ID card reading failed:" + t_strTemp); return ; } Donsee_Beep(); CString strTempA; CString strInfo; CString strType; strType = idInfo.certType; if (strType == "Y") //New version of permanent residence permit for foreigners { \t\t//Chinese name t_strTemp = idInfo.name; strTempA.Format(L"Chinese name:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//gender t_strTemp = idInfo.sex; strTempA.Format(L"Gender:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Number of certificate replacements t_strTemp = idInfo.certVersion; strTempA.Format(L"Number of certificate renewals:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//date of birth t_strTemp = idInfo.birthday; // strTempA.Format(L" IDINFO.birthday: "); strTempA.Format(L"Birth:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //The English name needs to be combined with the English name to be the complete English name. t_strTemp = idInfo.ENfullname; strTempA.Format(L"English name:"); strInfo = strTempA; strInfo + = t_strTemp; strInfo + = idInfo.Other; // English name alternative InsertInfo(strInfo); //Certificate number t_strTemp = idInfo.number; strTempA.Format(L"Permanent residence permit number:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //start date t_strTemp = idInfo.signdate; strTempA.Format(L"Validity period starts:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//expiration date t_strTemp = idInfo.validterm; // strTempA.Format(L" IDINFO.validterm: "); strTempA.Format(L"Validity period ends:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Nationality code strTempA.Format(L"Nationality:"); t_strTemp = idInfo.people; strInfo = strTempA; strInfo + = t_strTemp; strInfo + = "/" ; t_strTemp = idInfo.Nationality; strInfo + = t_strTemp; InsertInfo(strInfo); //The current application acceptance agency t_strTemp = idInfo.organs; strTempA.Format(L"The current application acceptance agency:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Document identifier t_strTemp = idInfo.certType; strTempA.Format(L"Document type (ID card is "0", Hong Kong, Macao and Taiwan is "J", foreigners are "I, Y)":"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Previous versions if(strcmp(idInfo.address,"") == 0) InsertInfo(L"Previous version of permanent residence permit number: None"); else { t_strTemp = idInfo.address; strTempA.Format(L"Previous version of permanent residence permit number:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); } } else if (strType == "I") //2017 version of permanent residence permit for foreigners { \t\t//English name t_strTemp = idInfo.ENfullname; strTempA.Format(L"English name:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//gender t_strTemp = idInfo.sex; strTempA.Format(L"Gender:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Permanent residence number t_strTemp = idInfo.number; strTempA.Format(L"Permanent residence permit number:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Nationality code strTempA.Format(L"Nationality:"); t_strTemp = idInfo.people; strInfo = strTempA; strInfo + = t_strTemp; strInfo + = "/" ; t_strTemp = idInfo.Nationality; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//Chinese name t_strTemp = idInfo.name; strTempA.Format(L"Chinese name:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//Date of issue t_strTemp = idInfo.signdate; strTempA.Format(L"Validity period starts:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Expiration date t_strTemp = idInfo.validterm; strTempA.Format(L"Validity period ends:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//date of birth t_strTemp = idInfo.birthday; strTempA.Format(L"Birth:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Certificate version t_strTemp = idInfo.certVersion; strTempA.Format(L"Certificate version:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //The current application acceptance agency t_strTemp = idInfo.organs; strTempA.Format(L"The current application acceptance agency:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Document identifier t_strTemp = idInfo.certType; strTempA.Format(L"Document type (ID card is "0", Hong Kong, Macao and Taiwan is "J", foreigners are "I, Y)":"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); } else if (strType == "J") //Residence permit for Hong Kong, Macao and Taiwan residents { \t\t//Name t_strTemp = idInfo.name; strTempA.Format(L"Name:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//gender t_strTemp = idInfo.sex; strTempA.Format(L"Gender:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//date of birth t_strTemp = idInfo.birthday; strTempA.Format(L"Birth:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//address t_strTemp = idInfo.address; strTempA.Format(L"Address:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Certificate number t_strTemp = idInfo.number; strTempA.Format(L"Hong Kong, Macao and Taiwan residence permit number:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//issuing authority t_strTemp = idInfo.organs; strTempA.Format(L"Issuing authority:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //start date t_strTemp = idInfo.signdate; strTempA.Format(L"Validity period starts:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//expiration date t_strTemp = idInfo.validterm; strTempA.Format(L"Validity period ends:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //pass number t_strTemp = idInfo.passNu; strTempA.Format(L"Pass number:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Number of issuances t_strTemp = idInfo.signCount; strTempA.Format(L"Number of issuances:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Document identifier t_strTemp = idInfo.certType; strTempA.Format(L"Document type (ID card is "0", Hong Kong, Macao and Taiwan is "J", foreigners are "I, Y)":"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); } else //strType == "0" Resident ID card { \t\t//Name t_strTemp = idInfo.name; strTempA.Format(L"Name:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//gender t_strTemp = idInfo.sex; strTempA.Format(L"Gender:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//nationality t_strTemp = idInfo.people; strTempA.Format(L"Ethnicity:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//date of birth t_strTemp = idInfo.birthday; strTempA.Format(L"Birth:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //address t_strTemp = idInfo.address; strTempA.Format(L"Address:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Certificate number t_strTemp = idInfo.number; strTempA.Format(L"ID card number:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//issuing authority t_strTemp = idInfo.organs; strTempA.Format(L"Issuing authority:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //start date t_strTemp = idInfo.signdate; strTempA.Format(L"Validity period starts:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); \t\t//expiration date t_strTemp = idInfo.validterm; strTempA.Format(L"Validity period ends:"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); //Document identifier t_strTemp = idInfo.certType; strTempA.Format(L"Document type (ID card is "0", Hong Kong, Macao and Taiwan is "J", foreigners are "I, Y)":"); strInfo = strTempA; strInfo + = t_strTemp; InsertInfo(strInfo); } CString t_str1, t_str2; if (t_nType != 0) { t_str2 = idInfo.Photo; strTempA.Format(L"Avatar information 1024 bytes intercepted 50 bytes display: "); strInfo = strTempA; strInfo + = t_str2.Left(50); strInfo + = "..."; InsertInfo(strInfo); } \t if (t_nType == 2) { t_str2 = "" ; for (int i = 0; i < 1024; i + + ) { t_str1.Format(_T(" X"),(unsigned char)idInfo.figData[i]); t_str2 + = t_str1; } strTempA.Format(L"Fingerprint information 1024 bytes intercepted 50 bytes display: "); strInfo = strTempA; strInfo + = t_str2.Left(50); strInfo + = "..."; InsertInfo(strInfo); } if (t_nType == 0x00)//No need to load images at this time return ; int nLeft = m_rtPicShow.left + (m_rtPicShow.right-m_rtPicShow.left)/2 - 102/2; int nTop = m_rtPicShow.top + (m_rtPicShow.bottom-m_rtPicShow.top)/2 - 126/2; pWnd->SetWindowPos( NULL,nLeft,nTop,102,126,SWP_NOZORDER); //Set the size of the edit control to (100,80) and the position remains unchanged HDC hDC; int nWidth; int nHeight; if (!m_imPhoto.IsNull()) m_imPhoto.Destroy(); m_imPhoto.Load(CString(t_szPicPath)); m_bPhoto = TRUE; m_Static_Photo.GetClientRect( & amp;m_rPhoto); hDC = ::GetDC(m_Static_Photo.m_hWnd); nWidth = m_imPhoto.GetWidth(); nHeight = m_imPhoto.GetHeight(); m_rPhoto.left = (m_rPhoto.Width()-nWidth) / 2; m_rPhoto.right = m_rPhoto.left + nWidth; m_rPhoto.top = (m_rPhoto.Height()-nHeight) / 2; m_rPhoto.bottom = m_rPhoto.top + nHeight; m_imPhoto.Draw(hDC, m_rPhoto); ::ReleaseDC(m_Static_Photo.m_hWnd, hDC); // InsertInfo(L"Get ID card successfully"); return ; }